alper
1
I'm trying to add a 4 neighbours iterator to a Vec.
How do I make an iterator that contains 1 or more elements that can be non-contiguously indexed in the vector?
I'm poking at it with something like this, but nobody is very happy with this:
pub fn iter_four_neighbors(&self, row: usize, col: usize) -> Empty<&T> {
if row < self.rows && col < self.cols {
let i = iter::empty::<&T>();
if row > 0 { // N
// i.chain(iter::once(*self.get(row-1, col).unwrap()));
let b = &self.data[row * self.cols + col];
i.chain(iter::once(b));
}
Alos I think there was a grid class that implemented 4 and 8 neighbours (so I could look how they did it), but I can't quite find it at the moment.
Here's one way.
fn neighbors(&self, row: usize, col: usize) -> [Option<&T>; 4] {
if row < self.rows && col < self.cols {
// ... test boundary conditions to build array ...
} else {
[None; 4]
}
}
fn iter_neighbors(&self, row: usize, col: usize) -> impl Iterator<Item=&T> {
self.neighbors(row, col).into_iter().flatten()
}
1 Like
alper
3
Oh sorry, I should read the whole thing!
There's also something like
fn neighbors(x: usize, y: usize) -> impl Iterator<Item=usize> {
let rows = 4; let cols = 4;
(if x == 0 { None } else { Some((x - 1, y)) }).into_iter()
.chain(if x == cols - 1 { None } else { Some((x + 1, y)) })
.chain(if y == 0 { None } else { Some((x, y - 1)) })
.chain(if y == rows - 1 { None } else { Some((x, y + 1)) })
.map(|(x, y)| x * 10 + y) // get the &T here instead
}
alper
5
What I don't get about the library either is why the functions have a signature like this:
pub fn iter_row(&self, row: usize) -> Iter<T>
I would think they might return Iter<&T>
instead like in your example.
Iter<T>
(which is probably short for Iter<'_, T>
) can still implement Iterator<Item=&T>
.
1 Like
system
Closed
7
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.