Hacker Timesnew | past | comments | ask | show | jobs | submitlogin

I generally just write it like this:

   let new_array: Vec<_> = array.into_iter()
        .filter(|&x| x != 0)
        .map(|x| x * 2)
        .collect();
I'm actually a bit confused by the `&x` given that `into_iter()` is used, which would take ownership of the array values, but assuming that it was supposed to be just `iter()` (or that it's an array of &i32 or something I guess), you're going to be copying the integer when dereferencing, so I'd probably just use `Iterator::copied` if I was worried about too many symbols being unreadable:

   let new_array: Vec<_> = array.iter()
        .copied()
        .filter(|x| x != 0)
        .map(|x| x * 2)
        .collect();
There's also `Iterator::filter_map` to combine `filter` and `map`, although that might end up seeming less readable to some due to the need for an Option, and due to the laziness of iterators, it will be collected in a single pass either way:

   let new_array: Vec<_> = array.iter()
        .copied()
        .filter_map(|x| if x == 0 { None } else { Some(x * 2) })
        .collect();
This is definitely more verbose than Python, but that's because the syntax needs to disambiguate between owned and copied values and account for static types (e.g. needing to annotate to specify the return type of `collect`, since you could be collecting into almost any collection type you want). It's probably not possible to handle all those cases with syntax as minimal as Python, but if you are fine with not having fine-grained control over that, it's possible to define that simpler syntax with a macro! There seem to be a lot of these published so far (https://crates.io/search?q=comprehension), but to pick one that supports the exact same syntax in the Python example, https://crates.io/crates/comprende seems to do the trick:

    let array = [0, 1, 2, 3];
    let new_array = c![x * 2 for x in array if x != 0];
    println!("{:?}", new_array); // Prints [2, 4, 6]
I'm not trying to argue that Rust is a 1:1 replacement to Python or that if Python suits your needs, you shouldn't use it; I think it's worth pointing out that Rust has more complex syntax for a reason though, and that it has surprisingly good support for syntactic sugar that lets you trade some control for expressiveness that can alleviate some of the pain you might otherwise run into.


It actually needs the & in both my example and your second example, because .filter receives a reference to the item being iterated. Your second example doesn't compile: https://play.rust-lang.org/?version=stable&mode=debug&editio...


Ah, you're right! I had forgotten filter worked like that. I'll have to concede that equality with references to `Copy` is somewhat annoying when dealing with closures (and closures in general are one of the few parts of Rust I do consistently wish had better ergonomics, although I understand why it's hard).




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: