Как вернуть итератор для двумерного массива с включенными индексами перечисления? - PullRequest
0 голосов
/ 15 сентября 2018

У меня есть структура, содержащая 2D-массив:

struct Block;

struct World {
    blocks: [[Block; 10]; 10],
}

Как написать функцию, которая возвращает итератор для двумерного массива, но с включенными индексами перечисления?

fn enumerate_blocks(&self) -> impl Iterator<Item = (usize, usize, &Block)>

Мне удалось написать реализацию функции, которая просто возвращает итератор без индексов перечисления:

fn blocks(&self) -> impl Iterator<Item = &Block> {
    self.blocks.iter().flat_map(|x| x.iter())
}

Если я вызову Iterator::enumerate один раз, я получу итератор через (usize, [B; 10]) с. Что я могу сделать дальше, чтобы получить итератор для (usize, usize, B) s?

Я знаю, что мог бы заставить функцию возвращать пользовательскую структуру, а затем реализовать Iterator, как это делает image, но в идеале я бы хотел этого избежать.

1 Ответ

0 голосов
/ 15 сентября 2018

Если я вызову Iterator::enumerate один раз, я получу итератор через (usize, [B; 10]) с.Что я могу сделать дальше, чтобы получить итератор для (usize, usize, B) s?

Вызов Iterator::enumerate для внутреннего массива таким же образом, продолжая использовать Iterator::flat_map объединить их.Используйте Iterator::map, чтобы добавить внешний индекс к внутреннему кортежу.

#[derive(Debug, Default)]
struct Block;

#[derive(Debug, Default)]
struct World {
    blocks: [[Block; 2]; 3],
}

impl World {
    fn blocks(&self) -> impl Iterator<Item = (usize, usize, &Block)> {
        self.blocks
            .iter()
            .enumerate()
            .flat_map(|(x, v)| v.iter().enumerate().map(move |(y, v)| (x, y, v)))
    }
}

fn main() {
    let w = World::default();
    for (x, y, v) in w.blocks() {
        println!("{}, {}, {:?}", x, y, v)
    }
}
0, 0, Block
0, 1, Block
1, 0, Block
1, 1, Block
2, 0, Block
2, 1, Block
...