I have a Board (a.k.a. &mut Vec) which I would like to update while iterating over it. The new value I want to update wi
It entirely depends on your next_gen function. Assuming we know nothing about the function except its signature, the easiest way is to use indices:
fn step(board: &mut Board) {
for row_index in 0..board.len() {
for column_index in 0..board[row_index].len() {
let cell_next = next_gen((row_index, column_index), &board);
if board[row_index][column_index] != cell_next {
board[row_index][column_index] = cell_next;
}
}
}
}
With more information about next_gen a different solution might be possible, but it sounds a lot like a cellular automaton to me, and to the best of my knowledge this cannot be done in an iterator-way in Rust without changing the type of Board.
You might fear that the indexing solution will be less efficient than an iterator solution, but you should trust LLVM on this. In case your next_gen function is in another crate, you should mark it #[inline] so LLVM can optimize it too (not necessary if everything is in one crate).
Not an answer to your question, but to your problem:
Since you are implementing Conway's Game of Life, you cannot do the modification in-place. Imagine the following pattern:
00000
00100
00100
00100
00000
If you update line 2, it will change the 1 in that line to a 0 since it has only two 1s in its neighborhood. This will cause the middle 1 to see only two 1s instead of the three that were there to begin with. Therefor you always need to either make a copy of the entire Board, or, as you did in your code, write all the changes to some other location, and splice them in after going through the entire board.