Indices of true values My task is to find the indices of a vector of booleans that are true. I'm coming from a JavaScript background and would like to learn how to write this in idiomatic Rust.

fn main() {
    let fold_func = |acc: Vec&lt;usize&gt;, p: (usize, &amp;bool)| -&gt; Vec&lt;usize&gt; {
        if *p.1 {
            let mut clone = acc.clone();
            clone.push(p.0);
            clone
        } else {
            acc
        }
    };
    let v = vec![true,false,true];
    let result = v.iter().enumerate().fold(vec![], fold_func);
    print!("{:?}", result) //[0, 2]
}
Spaces come after commas

-    let v = vec![true,false,true];
+    let v = vec![true, false, true];

Define the closure inline in the fold call. This allows removing the explicit types
Cloning the accumulator is more expensive than it needs to be. You have been given ownership of the vector, just declare it mutable and push to it.


The code now looks like:

let result = v.iter().enumerate().fold(vec![], |mut acc, p| {
    if *p.1 {
        acc.push(p.0);
        acc
    } else {
        acc
    }
});



Extract out the common part of the closure that returns the acc
Destructure p to give the components names.


The code now looks like:

let result = v.iter().enumerate().fold(vec![], |mut acc, (index, value)| {
    if *value {
        acc.push(index);
    }
    acc
});



I advocate to basically memorize all the methods on Iterator. In this case, filter, map, and collect allow writing the entire thing more succinctly, equally efficiently, as well as more flexibly.
There's no need to allocate the Vec, an array / slice works the same.


The code now looks like:

fn main() {
    let v = [true, false, true];

    let result: Vec&lt;_&gt; = v.iter()
        .enumerate()
        .filter(|&amp;(_, &amp;value)| value)
        .map(|(index, _)| index)
        .collect();

    println!("{:?}", result);
}





  I would expect that filter() filters out non true values, so indices would shift, but it seems like it's not happening


Yes, filter does remove the non-true values. The important thing to recognize is where the indices are added.

With iter().enumerate().filter(), enumeration happens before the filtering. Each index is added based on an unfiltered iterator.

If the code had instead been iter().filter().enumerate(), the enumeration happening after the filtering, then the index would have been added based on the filtered iterator. This would result in the indices 0, 1, 2, ..., which isn't very useful, as you point out.