How I can make this code work?

Ignore the purpose of this code; I just trimmed it down to this small example. Basically, what I want to do is:

fn main() {
  let mut vec = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5];


  for el in vec.iter_mut().filter(|n| **n % 2 == 0) {
    if vec.iter().filter(|c| *c % *el == 0).count() < *el {
      *el = 3;
    }
  } 
}

Obviously, I can't. What are the best practices to do it the Rusty way?

PS:

  • I need to use iterator over indexes
  • No clone

Either iterate over indices

for index in 0..vec.len() {
    let el = vec[index];
    if el % 2 != 0 {
        continue;
    }
    if vec.iter().filter(|c| *c % el == 0).count() < el {
        vec[index] = 3;
    }
}

Or use Cell

let cells = Cell::from_mut(vec.as_mut_slice()).as_slice_of_cells();

for el_cell in cells.iter().filter(|n| n.get() % 2 == 0) {
    let el = el_cell.get();
    if cells.iter().filter(|c| c.get() % el == 0).count() < el {
        el_cell.set(3);
    }
}

The current code is simple enough that nothing surprising happens, but if you're doing something more complex, keep in mind that el will become outdated if you write to vec[index] or el_cell.

3 Likes

thanks for replaying @drewtato , the second point it is the one that is interesting for me after a quick search i find that Cell is good for types that its ok to copy as they say in docs.rs, but in my case i don't want to use copy and the performance is the most important in my case

the first point is good if there is a way to get index to correspond elements from a complex iterator like this one

&creatures.values_mut().filter(|cr| cr.kind != CreatureKind::MONSTER).sorted_by_key(|cr| cr.id).chunks(2)

I know the example is simplified and not really illustrative of your actual use case, but I would be remiss to not point out that the example has quadratic time complexity. Which is absolutely not the most optimal way to implement the algorithm. So, it begs the question, what is your actual use case? What kinds of algorithmic analysis have you performed so far?

1 Like

thanks for interests @parasyte, i now i can change the algorithm so i can avoid this so you say this way its not rusty way?, i am used to make things first work and optimize after i achieved this by throwing Cells to things that change often inside my objects

FYI, the performance of the two methods I posted should be identical. The only thing Cell gives you here is the ability to write it in an iterative style.

Keep in mind that the Rust idea of copying has no bearing on what actually happens physically. This is even more true of moves, which have no real-life counterpart. If performance is important to you, try both and see which is faster.

1 Like