title: Rust 2D sub-window iterator
body: <p>I am using a <code>Vec</code> to store a 2D (row major) matrix of values. I would like to iterate over this matrix with a sliding 2D sub-window to apply a filter (which is unfortunately non-separable).</p>
  
  <p>I have seen in the slice documentation that a <code>windows</code> function exists, which is what I want but in 2 dimensions.</p>
  
  <p>I thought about implementing this as:</p>
  
  <pre><code>fn main() {
      // 4 rows 3 columns
      let dim: (usize, usize) = (4, 3);
      // Place-holder matrix
      #[rustfmt::skip]
      let mat = vec![0,  1,  2,
                     3,  4,  5,
                     6,  7,  8,
                     9, 10, 11];
  
      // 2D index to 1D index
      let linearize = |r, c| r * dim.1 + c;
      // The dimensions of my sub-window
      let win_size: usize = 2;
      // Calculate the bounds for which the top left corner of each window may exist
      let bounds: (usize, usize) = (dim.0 - win_size + 1, dim.1 - win_size + 1);
      // Convert window 1D index into a 2D index
      let split = |i| (i / win_size, i % win_size);
  
      // Iterate over all the top left corners
      let window_2d = (0..bounds.0 * bounds.1).map(|i| {
          // Get the 2D index of the top left corner
          let (r, c) = (i / bounds.1, i % bounds.1);
          // Borrow the matrix, so our closure may own the reference
          let bmat = &amp;mat;
          // Return an iterator for this window
          return (0..win_size * win_size).map(move |x| {
              let (wr, wc) = split(x);
              return bmat[linearize(wr + r, wc + c)];
          });
      });
  
      // Print the windows out
      window_2d.for_each(|it| {
          print!("[ ");
          it.for_each(|x| print!("{} ", x));
          println!("]");
      });
  }
  </code></pre>
  
  <p>Essentially creating an iterator over a range of indices and then mapping to the square bracket operator of the matrix. 
  As far as I know, this is going to have the overhead of a bounds check for each deref of the iterator.</p>
  
  <p>I'm wondering if there's an alternative which would elide the bounds checks? Maybe using a combination of <code>chunks</code>, <code>windows</code> and <code>zip</code>, to chunk the matrix into rows, each with a sliding window, then zip the row's windows and flatten the result?</p>
  
  <p>Thanks!</p>
  
  <p><strong>Edit</strong>:
  I'm not looking to simply iterate over a 2D array, I want to slide a 2D window over the array, similar to how the <code>std::slice::windows</code> function works.</p>