Repository: becheran/grid (language: rust)

Issue:
Feature request: Please add `indexed_iter()` to traverse the grid with row/col indexes
Mentioned as the title, I'm glad if we can have a `indexed_iter()`, and extension to `iter()` that adds row/col index to each item. That's a great convenience to avoid writing enumerated index by myself.


Discussion / hints:
@jerry73204 sounds like a good idea. Though, I won't find the time in the near future to implement it.

If anybody opens a PR on this, I am more than happy to merge it.

Fix patch:
diff --git a/src/lib.rs b/src/lib.rs
index 300b6f6..234df47 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -459,6 +459,32 @@ impl<T> Grid<T> {
         }
     }
 
+    /// Traverse the grid with row and column indexes.
+    /// 
+    /// # Examples
+    /// 
+    /// ```
+    /// use grid::*;
+    /// let grid: Grid<u8> = grid![[1,2][3,4]];
+    /// let mut iter = grid.indexed_iter();
+    /// assert_eq!(iter.next(), Some(((0, 0), &1)));
+    /// ```
+    /// 
+    /// Or simply unpack in a `for`  loop:
+    /// 
+    /// ```
+    /// use grid::*;
+    /// let grid: Grid<u8> = grid![[1,2][3,4]];
+    /// for ((row, col), i) in grid.indexed_iter() {
+    ///     println!("value at row {row} and column {col} is: {i}");
+    /// }
+    /// ```
+    pub fn indexed_iter(&self) -> impl Iterator<Item=((usize, usize), &T)> {
+        self.data.iter().enumerate().map(move |(idx, i)| 
+            ((idx / self.cols, idx % self.cols), i)
+        )
+    }
+
     /// Add a new row to the grid.
     ///
     /// # Examples
@@ -1370,6 +1396,24 @@ mod test {
         assert_eq!(iter.next(), None);
     }
 
+    #[test]
+    fn indexed_iter() {
+        let grid: Grid<u8> = grid![[1,2][3,4]];
+        let mut iter = grid.indexed_iter();
+        assert_eq!(iter.next(), Some(((0, 0), &1)));
+        assert_eq!(iter.next(), Some(((0, 1), &2)));
+        assert_eq!(iter.next(), Some(((1, 0), &3)));
+        assert_eq!(iter.next(), Some(((1, 1), &4)));
+        assert_eq!(iter.next(), None);
+    }
+
+    #[test]
+    fn indexed_iter_empty() {
+        let grid: Grid<u8> = Grid::new(0, 0);
+        let mut iter = grid.indexed_iter();
+        assert_eq!(iter.next(), None);
+    }
+
     #[test]
     fn clear() {
         let mut grid: Grid<u8> = grid![[1, 2, 3]];


Test patch: