# Why Does .filter() dont work?

**URL:** <https://users.rust-lang.org/t/why-does-filter-dont-work/126174>\
**Category:** help\
**Created:** [February 24, 2025, 3:02pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174 "2025-02-24T15:02:44Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![faber\_soaks](https://avatars.discourse-cdn.com/v4/letter/f/b3f665/32.png) [@faber\_soaks](https://users.rust-lang.org/u/faber_soaks)\
**Post date:** [February 24, 2025, 3:02pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/1 "2025-02-24T15:02:44Z")

</div>

I understand that `.copied()` is used to take ownership of values and remove references so that `.filter()` can operate correctly. I could also use `.into_iter()` to achieve the same effect.

This works as expected:

```rust
fn main() {
    let numbers = [5, 10, 15, 20];

    let filtered: Vec<i32> = numbers.iter()
        .copied()
        .filter(|x| x % 2 == 0)
        .collect();

    println!("{:?}", filtered); // Output: [10, 20]
}

```

**However, Why this does not work as expected?**

```rust
fn main() {
    let numbers = [5, 10, 15, 20];

    let filtered: Vec<i32> = numbers.iter()
        .copied()
        .filter(|x| x > 2)
        .collect();

    println!("{:?}", filtered); // Expected: [5, 10, 15, 20], but something seems off.
}

```

Additionally, `.map()` seems to work fine with anything, unlike `.filter()`.

Could someone help clarify why `.filter()` behaves differently in these cases, and why `.map()` doesn’t have the same issue?

---

<div class="post-metadata">

**Author:** ![gbutler69](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/gbutler69/32/5596_2.png) [@gbutler69](https://users.rust-lang.org/u/gbutler69)\
**Post date:** [February 24, 2025, 3:09pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/2 "2025-02-24T15:09:23Z")

</div>

~~That can't be the code that is not working for you. That will definitely work.~~

Oops!

---

<div class="post-metadata">

**Author:** ![jpleyer](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jpleyer/32/33848_2.png) [@jpleyer](https://users.rust-lang.org/u/jpleyer)\
**Post date:** [February 24, 2025, 3:10pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/3 "2025-02-24T15:10:37Z")

</div>

By calling `[..].iter()` you create an iterator over borrowed values `&i32`. When again calling `.copied()` you copy the iterator over said borrowed values. This means in both cases we are iterating over values of type `&i32`.

The `%` operator seems to work just fine with borrowed values while a comparison with `> 2` requires a value rather than a reference.

You simply need to dereference the value `x` in your second example in order to work.

> **[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=522db2479f573a298a05a474d0ec3f2f)**
>
> A browser interface to the Rust compiler to experiment with the language

---

<div class="post-metadata">

**Author:** ![jameseb7](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jameseb7/32/13257_2.png) [@jameseb7](https://users.rust-lang.org/u/jameseb7)\
**Post date:** [February 24, 2025, 3:12pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/4 "2025-02-24T15:12:43Z")

</div>

The function passed to `filter()` always takes a reference, since it isn't supposed to take ownership of or change the items, only inspect them. The function passed to `map()`, on the other hand, _is_ supposed change the items, and outputs the thing it maps to so it makes sense for it to take ownership.

The error message your code generates also suggests a simple fix: either dereference `x` or reference the `2` so that they have the same type.

---

<div class="post-metadata">

**Author:** ![faber\_soaks](https://avatars.discourse-cdn.com/v4/letter/f/b3f665/32.png) [@faber\_soaks](https://users.rust-lang.org/u/faber_soaks)\
**Post date:** [February 24, 2025, 3:14pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/5 "2025-02-24T15:14:02Z")

</div>

copy the 2 code and run here in this online compiler ,its not working

> **[Online Rust Compiler - Programiz](https://www.programiz.com/rust/online-compiler/)**
>
> Write and run your Rust code using our online compiler. Enjoy additional features like code sharing, dark mode, and support for multiple programming languages.

---

<div class="post-metadata">

**Author:** ![cod10129](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/cod10129/32/33671_2.png) [@cod10129](https://users.rust-lang.org/u/cod10129)\
**Post date:** [February 24, 2025, 3:20pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/6 "2025-02-24T15:20:33Z")

</div>

That website doesn’t save the code — when I open it I just see a hello world. Please use the [Rust Playground](https://play.rust-lang.org) for sharing code snippets.\[1\]

I created [this playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=5846a9510621774d550d43167624bae5) with your code.

The reason for your problem is that `Iterator::filter`’s closure takes **`&`** `Iterator::Item`, which means the closure always gets a reference, even if the iterator is over values. (Also see [Why Does .filter() dont work? - #4 by jameseb7](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/4))

* * *

1. And when you do, make sure you click “Share” to get a permalink that will actually link to your code

---

<div class="post-metadata">

**Author:** ![faber\_soaks](https://avatars.discourse-cdn.com/v4/letter/f/b3f665/32.png) [@faber\_soaks](https://users.rust-lang.org/u/faber_soaks)\
**Post date:** [February 24, 2025, 3:30pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/7 "2025-02-24T15:30:01Z")

</div>

Yes, I got that from the error, but what's the logic? Just a simple change in a condition caused this error. What else I need to be aware of along these lines, as this seems quite unusual

---

<div class="post-metadata">

**Author:** ![jameseb7](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jameseb7/32/13257_2.png) [@jameseb7](https://users.rust-lang.org/u/jameseb7)\
**Post date:** [February 24, 2025, 3:43pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/8 "2025-02-24T15:43:47Z")

</div>

> [@jpleyer](#):
>
> By calling `[..].iter()` you create an iterator over borrowed values `&i32`. When again calling `.copied()` you copy the iterator over said borrowed values. This means in both cases we are iterating over values of type `&i32`.

That's not true: [`copied()`](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.copied) copies the items iterated over, not the iterator, so the iterator after `.copied()` is over values of type `i32`.

> [@faber\_soaks](#):
>
> Yes, I got that from the error, but what's the logic? Just a simple change in a condition caused this error. What else I need to be aware of along these lines, as this seems quite unusual

It's just that `x` is of type `&i32` and `2` is if type `i32`, and comparison operators are generally only implemented on things of the same type. The `%` operator, on the other hand, is implemented for all the combinations of `&T` and `T`. The reason for this isn't clear though.

---

<div class="post-metadata">

**Author:** ![derspiny](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/derspiny/32/3540_2.png) [@derspiny](https://users.rust-lang.org/u/derspiny)\
**Post date:** [February 24, 2025, 4:05pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/9 "2025-02-24T16:05:42Z")

</div>

The compiler explains:

```rust
   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
 --> src/main.rs:6:25
  |
6 | .filter(|x| x > 2)
  | ^ expected `&_`, found integer
  |
  = note: expected reference `&_`
                  found type `{integer}`
help: consider dereferencing the borrow
  |
6 | .filter(|x| *x > 2)
  | +

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 1 previous error

```

When you have an iterator of type `T`, `filter` takes a `FnMut(&T) -> bool`, which means that your closure's `x` argument has type `&i32`. `&i32` and `i32` are not comparable, but dereferencing the `x` argument produces an `i32`, which _is_ comparable with another `i32`.

This doesn't happen with your `|x| x % 2 == 0` example because the stdlib has an implementation of `Rem<&i32> for i32`, which is used for the `x % 2` part of your filter function.

Adding the suggested asterisk produces a program that prints `[5, 10, 15, 20]`, as you expect.

---

<div class="post-metadata">

**Author:** ![jumpnbrownweasel](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jumpnbrownweasel/32/17403_2.png) [@jumpnbrownweasel](https://users.rust-lang.org/u/jumpnbrownweasel)\
**Post date:** [February 24, 2025, 4:35pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/10 "2025-02-24T16:35:48Z")

</div>

> [@faber\_soaks](#):
>
> I understand that `.copied()` is used to take ownership of values and remove references so that `.filter()` can operate correctly.

No, you don't need to use `copied` to make `filter` operate correctly. You can dereference the values in the closure when needed, and comparisons can be done with references. It seems that you're not aware of the types of the variables during the iteration.

I suggest looking at the type of the variables you're using. If you're using rust-analyzer in your editor, you can "hover" over the variable to see the type. This will show you whether the variables are a reference (or not) so you can easily see whether they need to be dereferenced.

And of course the doc and the compiler error will also tell you this information. Another approach is to add type annotations to the variables with the type you expect, to see whether this causes a compiler error or not.

If you're not using rust-analyzer, I strongly recommend it. You'll see the compiler errors in your editor, which speeds up the process of finding the problems and fixing them.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [May 25, 2025, 4:36pm UTC](https://users.rust-lang.org/t/why-does-filter-dont-work/126174/11 "2025-05-25T16:36:04Z")

</div>

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
