For example, how could I find the positions that contain the value 20 in the following 2D array?
let nested_array = [
[17, 16, 15, 14, 13],
[18, 5, 4, 3, 12],
[19, 6, 1, 2, 11],
[20, 7, 8, 9, 10],
[21, 20, 23, 24, 25],
];
Values might not be unique.
>Solution :
You could either roll your own for loop. Alternatively, you can use find() or more specifically find_map() and position():
let find = 20;
let pos = nested_array.iter().enumerate().find_map(|(i, arr)| {
let j = arr.iter().position(|&x| x == find)?;
Some((i, j))
});
We can assert that we get the correct value:
let (i, j) = pos.unwrap();
let val = nested_array[i][j];
assert_eq!(i, 3);
assert_eq!(j, 0);
assert_eq!(val, find);
If you want to find multiple instances of 20. Then you simply need to replace find_map() with filter_map():
let positions = nested_array.iter().enumerate().filter_map(|(i, arr)| {
let j = arr.iter().position(|&x| x == find)?;
Some((i, j))
});
If you can have multiple instances of 20 in the same row, then you can do something like this:
let positions = nested_array
.iter()
.enumerate()
.flat_map(|(i, arr)| {
let arr = arr.iter().enumerate();
std::iter::repeat(i).zip(arr)
})
.filter_map(|(i, (j, &val))| (val == find).then_some((i, j)));
All of this can of course be written in a few variations. So the main take away is find_map(), filter_map(), and position().