array2d/lib.rs
1//! Array2D provides a fixed sized two-dimensional array. It is more efficient
2//! and is easier to use than a vector of vectors, i.e. `Vec<Vec<T>>`.
3//!
4//! This is beneficial when using a grid-like structure, which is common in
5//! image processing, game boards, and other situations. Array2D cannot be used
6//! when rows or columns might have different lengths—all rows and columns must
7//! be the same length.
8//!
9//! # How to use [`Array2D`]
10//!
11//! ## Creating an [`Array2D`]
12//!
13//! An [`Array2D`] can be created in many different ways. These include:
14//! - Providing the rows or the columns, which must all be the same size (see
15//! [`from_rows`] and [`from_columns`]).
16//! - Providing a "flat" slice of elements in either [row major or column
17//! major order] along with the dimensions, which must match the number of
18//! elements in the slice (see [`from_row_major`] and
19//! [`from_column_major`]).
20//! - Providing a value to repeatedly put in every location (see
21//! [`filled_with`]).
22//! - Providing a generator function that is repeatedly called to produce
23//! values to fill the array (see [`filled_by_row_major`] and
24//! [`filled_by_column_major`]).
25//! - Providing an iterator that is used to produce values to fill the array
26//! (see [`from_iter_row_major`] and [`from_iter_column_major`]).
27//!
28//! ## Accessing data from an [`Array2D`]
29//!
30//! [`Array2D`] supports several forms of indexing:
31//! - Using the indexing syntax (square brackets) with a tuple of [`(usize,
32//! usize)`], which panics on out-of-bounds accesses.
33//! - Using the [`get`], [`get_mut`], and [`set`] methods, which return an
34//! [`Option`] or a [`Result`] on out-of-bounds accesses.
35//! - Using the row major or column major version of these methods,
36//! i.e. [`get_row_major`], [`get_mut_row_major`], [`set_row_major`],
37//! [`get_column_major`], [`get_mut_column_major`],
38//! [`set_column_major`]. These perform the same tasks as the non row/column
39//! major methods, but take one index instead of two.
40//!
41//! [`Array2D`] also supports several forms of iteration. You can iterate
42//! through:
43//! - All of the elements, in either [row major or column major order] (see
44//! [`elements_row_major_iter`] and [`elements_column_major_iter`]).
45//! - Individual rows or columns (see [`row_iter`] and [`column_iter`]).
46//! - All rows or all columns (see [`rows_iter`] and [`columns_iter`]).
47//!
48//! ## Extracting all data from an [`Array2D`]
49//!
50//! An [`Array2D`] can be converted back into a [`Vec`] through several
51//! methods. You can extract the data as:
52//! - A [`Vec`] of rows or columns (see [`as_rows`] and [`as_columns`]).
53//! - A "flat" [`Vec`] of elements in either [row major or column major order]
54//! (see [`as_row_major`] and [`as_column_major`]).
55//!
56//! # Examples
57//!
58//! ```rust
59//! use array2d::{Array2D, Error};
60//!
61//! pub fn main() -> Result<(), Error> {
62//! // Create an array filled with the same element.
63//! let prefilled = Array2D::filled_with(42, 2, 3);
64//! assert_eq!(prefilled.num_rows(), 2);
65//! assert_eq!(prefilled.num_columns(), 3);
66//! assert_eq!(prefilled[(0, 0)], 42);
67//!
68//! // Create an array from the given rows. You can also use columns
69//! // with the `columns` function
70//! let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
71//! let from_rows = Array2D::from_rows(&rows)?;
72//! assert_eq!(from_rows.num_rows(), 2);
73//! assert_eq!(from_rows.num_columns(), 3);
74//! assert_eq!(from_rows[(1, 1)], 5);
75//!
76//! // Create an array from a flat Vec of elements in row major or
77//! // column major order.
78//! let column_major = vec![1, 4, 2, 5, 3, 6];
79//! let from_column_major =
80//! Array2D::from_column_major(&column_major, 2, 3)?;
81//! assert_eq!(from_column_major.num_rows(), 2);
82//! assert_eq!(from_column_major.num_columns(), 3);
83//! assert_eq!(from_column_major[(1, 1)], 5);
84//!
85//! // Implements `Eq` if the element type does.
86//! assert_eq!(from_rows, from_column_major);
87//!
88//! // Index into an array using a tuple of usize to access or alter
89//! // the array.
90//! let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
91//! let mut array = Array2D::from_rows(&rows)?;
92//! array[(1, 1)] = 100;
93//!
94//! // Convert the array back into a nested Vec using `as_rows` or
95//! // `as_columns`.
96//! let array_rows = array.as_rows();
97//! assert_eq!(array_rows, vec![vec![1, 2, 3], vec![4, 100, 6]]);
98//!
99//! // Convert the array back into a flat Vec using `as_row_major` or
100//! // `as_column_major`.
101//! let array_column_major = array.as_column_major();
102//! assert_eq!(array_column_major, vec![1, 4, 2, 100, 3, 6]);
103//!
104//! // Iterate over a single row or column
105//! println!("First column:");
106//! for element in array.column_iter(0)? {
107//! println!("{}", element);
108//! }
109//!
110//! // Iterate over all rows or columns.
111//! println!("All elements:");
112//! for row_iter in array.rows_iter() {
113//! for element in row_iter {
114//! print!("{} ", element);
115//! }
116//! println!();
117//! }
118//!
119//! Ok(())
120//! }
121//! ```
122//!
123//! [`Array2D`]: struct.Array2D.html
124//! [`from_rows`]: struct.Array2D.html#method.from_rows
125//! [`from_columns`]: struct.Array2D.html#method.from_columns
126//! [`from_row_major`]: struct.Array2D.html#method.from_row_major
127//! [`from_column_major`]: struct.Array2D.html#method.from_column_major
128//! [`filled_with`]: struct.Array2D.html#method.filled_with
129//! [`filled_by_row_major`]: struct.Array2D.html#method.filled_by_row_major
130//! [`filled_by_column_major`]: struct.Array2D.html#method.filled_by_column_major
131//! [`from_iter_row_major`]: struct.Array2D.html#method.from_iter_row_major
132//! [`from_iter_column_major`]: struct.Array2D.html#method.from_iter_column_major
133//! [`get`]: struct.Array2D.html#method.get
134//! [`get_mut`]: struct.Array2D.html#method.get_mut
135//! [`set`]: struct.Array2D.html#method.set
136//! [`get_row_major`]: struct.Array2D.html#method.get_row_major
137//! [`get_mut_row_major`]: struct.Array2D.html#method.get_mut_row_major
138//! [`set_row_major`]: struct.Array2D.html#method.set_row_major
139//! [`get_column_major`]: struct.Array2D.html#method.get_column_major
140//! [`get_mut_column_major`]: struct.Array2D.html#method.get_mut_column_major
141//! [`set_column_major`]: struct.Array2D.html#method.set_column_major
142//! [`elements_row_major_iter`]: struct.Array2D.html#method.elements_row_major_iter
143//! [`elements_column_major_iter`]: struct.Array2D.html#method.elements_column_major_iter
144//! [`row_iter`]: struct.Array2D.html#method.row_iter
145//! [`column_iter`]: struct.Array2D.html#method.column_iter
146//! [`rows_iter`]: struct.Array2D.html#method.rows_iter
147//! [`columns_iter`]: struct.Array2D.html#method.columns_iter
148//! [`as_rows`]: struct.Array2D.html#method.as_rows
149//! [`as_columns`]: struct.Array2D.html#method.as_columns
150//! [`as_row_major`]: struct.Array2D.html#method.as_row_major
151//! [`as_column_major`]: struct.Array2D.html#method.as_column_major
152//! [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
153//! [`Option`]: https://doc.rust-lang.org/std/option/
154//! [`Result`]: https://doc.rust-lang.org/std/result/
155//! [`(usize, usize)`]: https://doc.rust-lang.org/std/primitive.usize.html
156//! [row major or column major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
157
158#![deny(missing_docs)]
159
160use std::fmt::{Display, Formatter};
161use std::ops::{Index, IndexMut};
162
163#[cfg(feature = "serde")]
164use serde::{Deserialize, Serialize};
165
166/// A fixed sized two-dimensional array.
167#[derive(Debug, Clone, Eq, PartialEq, Hash)]
168#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
169pub struct Array2D<T> {
170 array: Vec<T>,
171 num_rows: usize,
172 num_columns: usize,
173}
174
175/// An error that can arise during the use of an [`Array2D`].
176///
177/// [`Array2D`]: struct.Array2D.html
178#[derive(Debug, Eq, PartialEq)]
179pub enum Error {
180 /// The given indices were out of bounds.
181 IndicesOutOfBounds(usize, usize),
182 /// The given index in row or column major order was out of bounds.
183 IndexOutOfBounds(usize),
184 /// The dimensions given did not match the elements provided
185 DimensionMismatch,
186 /// There were not enough elements to fill the array.
187 NotEnoughElements,
188}
189
190impl Display for Error {
191 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
192 match self {
193 Error::IndicesOutOfBounds(row, column) => write!(f, "indices ({row}, {column}) out of bounds"),
194 Error::IndexOutOfBounds(index) => write!(f, "index {index} out of bounds"),
195 Error::DimensionMismatch => write!(f, "dimension mismatch"),
196 Error::NotEnoughElements => write!(f, "not enough elements"),
197 }
198 }
199}
200
201impl std::error::Error for Error {}
202
203impl<T> Array2D<T> {
204 /// Creates a new [`Array2D`] from a slice of rows, each of which is a
205 /// [`Vec`] of elements.
206 ///
207 /// Returns an error if the rows are not all the same size.
208 ///
209 /// # Examples
210 ///
211 /// ```
212 /// # use array2d::{Array2D, Error};
213 /// # fn main() -> Result<(), Error> {
214 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
215 /// let array = Array2D::from_rows(&rows)?;
216 /// assert_eq!(array[(1, 2)], 6);
217 /// assert_eq!(array.as_rows(), rows);
218 /// # Ok(())
219 /// # }
220 /// ```
221 ///
222 /// [`Array2D`]: struct.Array2D.html
223 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
224 pub fn from_rows(elements: &[Vec<T>]) -> Result<Self, Error>
225 where
226 T: Clone,
227 {
228 let row_len = elements.get(0).map(Vec::len).unwrap_or(0);
229 if !elements.iter().all(|row| row.len() == row_len) {
230 return Err(Error::DimensionMismatch);
231 }
232 Ok(Array2D {
233 array: flatten(elements),
234 num_rows: elements.len(),
235 num_columns: row_len,
236 })
237 }
238
239 /// Creates a new [`Array2D`] from a slice of columns, each of which
240 /// contains a [`Vec`] of elements.
241 ///
242 /// Returns an error if the columns are not all the same size.
243 ///
244 /// # Examples
245 ///
246 /// ```
247 /// # use array2d::{Array2D, Error};
248 /// # fn main() -> Result<(), Error> {
249 /// let columns = vec![vec![1, 4], vec![2, 5], vec![3, 6]];
250 /// let array = Array2D::from_columns(&columns)?;
251 /// assert_eq!(array[(1, 2)], 6);
252 /// assert_eq!(array.as_rows(), vec![vec![1, 2, 3], vec![4, 5, 6]]);
253 /// # Ok(())
254 /// # }
255 /// ```
256 ///
257 /// [`Array2D`]: struct.Array2D.html
258 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
259 pub fn from_columns(elements: &[Vec<T>]) -> Result<Self, Error>
260 where
261 T: Clone,
262 {
263 let column_len = elements.get(0).map(Vec::len).unwrap_or(0);
264 if !elements.iter().all(|column| column.len() == column_len) {
265 return Err(Error::DimensionMismatch);
266 }
267 let num_rows = column_len;
268 let num_columns = elements.len();
269 let array = indices_row_major(num_rows, num_columns)
270 .map(|(row, column)| elements[column][row].clone())
271 .collect();
272 Ok(Array2D {
273 array,
274 num_rows,
275 num_columns,
276 })
277 }
278
279 /// Creates a new [`Array2D`] from the given flat slice in [row major
280 /// order].
281 ///
282 /// Returns an error if the number of elements in `elements` is not the
283 /// product of `num_rows` and `num_columns`, i.e. the dimensions do not
284 /// match.
285 ///
286 /// # Examples
287 ///
288 /// ```
289 /// # use array2d::{Array2D, Error};
290 /// # fn main() -> Result<(), Error> {
291 /// let row_major = vec![1, 2, 3, 4, 5, 6];
292 /// let array = Array2D::from_row_major(&row_major, 2, 3)?;
293 /// assert_eq!(array[(1, 2)], 6);
294 /// assert_eq!(array.as_rows(), vec![vec![1, 2, 3], vec![4, 5, 6]]);
295 /// # Ok(())
296 /// # }
297 /// ```
298 ///
299 /// [`Array2D`]: struct.Array2D.html
300 /// [row major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
301 pub fn from_row_major(
302 elements: &[T],
303 num_rows: usize,
304 num_columns: usize,
305 ) -> Result<Self, Error>
306 where
307 T: Clone,
308 {
309 let total_len = num_rows * num_columns;
310 if total_len != elements.len() {
311 return Err(Error::DimensionMismatch);
312 }
313 Ok(Array2D {
314 array: elements.to_vec(),
315 num_rows,
316 num_columns,
317 })
318 }
319
320 /// Creates a new [`Array2D`] from the given flat slice in [column major
321 /// order].
322 ///
323 /// Return an error if the number of elements in `elements` is not the
324 /// product of `num_rows` and `num_columns`, i.e. the dimensions do not
325 /// match.
326 ///
327 /// # Examples
328 ///
329 /// ```
330 /// # use array2d::{Array2D, Error};
331 /// # fn main() -> Result<(), Error> {
332 /// let column_major = vec![1, 4, 2, 5, 3, 6];
333 /// let array = Array2D::from_column_major(&column_major, 2, 3)?;
334 /// assert_eq!(array[(1, 2)], 6);
335 /// assert_eq!(array.as_rows(), vec![vec![1, 2, 3], vec![4, 5, 6]]);
336 /// # Ok(())
337 /// # }
338 /// ```
339 ///
340 /// [`Array2D`]: struct.Array2D.html
341 /// [column major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
342 pub fn from_column_major(
343 elements: &[T],
344 num_rows: usize,
345 num_columns: usize,
346 ) -> Result<Self, Error>
347 where
348 T: Clone,
349 {
350 let total_len = num_rows * num_columns;
351 if total_len != elements.len() {
352 return Err(Error::DimensionMismatch);
353 }
354 let indices_row_major =
355 (0..num_rows).flat_map(move |row| (0..num_columns).map(move |column| (row, column)));
356 let array = indices_row_major
357 .map(|(row, column)| {
358 let index = column * num_rows + row;
359 elements[index].clone()
360 })
361 .collect();
362 Ok(Array2D {
363 array,
364 num_rows,
365 num_columns,
366 })
367 }
368
369 /// Creates a new [`Array2D`] with the specified number of rows and columns
370 /// that contains `element` in every location.
371 ///
372 /// # Examples
373 ///
374 /// ```
375 /// # use array2d::{Array2D, Error};
376 /// let array = Array2D::filled_with(42, 2, 3);
377 /// assert_eq!(array.as_rows(), vec![vec![42, 42, 42], vec![42, 42, 42]]);
378 /// ```
379 ///
380 /// [`Array2D`]: struct.Array2D.html
381 pub fn filled_with(element: T, num_rows: usize, num_columns: usize) -> Self
382 where
383 T: Clone,
384 {
385 let total_len = num_rows * num_columns;
386 let array = vec![element; total_len];
387 Array2D {
388 array,
389 num_rows,
390 num_columns,
391 }
392 }
393
394 #[deprecated(since = "0.2.0", note = "Renamed to filled_with")]
395 /// Renamed to filled_with.
396 pub fn fill_with(element: T, num_rows: usize, num_columns: usize) -> Self
397 where
398 T: Clone,
399 {
400 Array2D::filled_with(element, num_rows, num_columns)
401 }
402
403 /// Creates a new [`Array2D`] with the specified number of rows and columns
404 /// and fills each element with the result of calling the given
405 /// function. The function is called once for every location going in
406 /// row major order.
407 ///
408 /// # Examples
409 ///
410 /// ```
411 /// # use array2d::{Array2D, Error};
412 /// let mut counter = 1;
413 /// let increment = || {
414 /// let tmp = counter;
415 /// counter += 1;
416 /// tmp
417 /// };
418 /// let array = Array2D::filled_by_row_major(increment, 2, 3);
419 /// assert_eq!(array.as_rows(), vec![vec![1, 2, 3], vec![4, 5, 6]]);
420 /// ```
421 ///
422 /// [`Array2D`]: struct.Array2D.html
423 pub fn filled_by_row_major<F>(mut generator: F, num_rows: usize, num_columns: usize) -> Self
424 where
425 F: FnMut() -> T,
426 {
427 let total_len = num_rows * num_columns;
428 let array = (0..total_len).map(|_| generator()).collect();
429 Array2D {
430 array,
431 num_rows,
432 num_columns,
433 }
434 }
435
436 /// Creates a new [`Array2D`] with the specified number of rows and columns
437 /// and fills each element with the result of calling the given
438 /// function. The function is called once for every location going in
439 /// column major order.
440 ///
441 /// # Examples
442 ///
443 /// ```
444 /// # use array2d::{Array2D, Error};
445 /// let mut counter = 1;
446 /// let increment = || {
447 /// let tmp = counter;
448 /// counter += 1;
449 /// tmp
450 /// };
451 /// let array = Array2D::filled_by_column_major(increment, 2, 3);
452 /// assert_eq!(array.as_columns(), vec![vec![1, 2], vec![3, 4], vec![5, 6]]);
453 /// ```
454 ///
455 /// [`Array2D`]: struct.Array2D.html
456 pub fn filled_by_column_major<F>(mut generator: F, num_rows: usize, num_columns: usize) -> Self
457 where
458 F: FnMut() -> T,
459 T: Clone,
460 {
461 let total_len = num_rows * num_columns;
462 let array_column_major = (0..total_len).map(|_| generator()).collect::<Vec<_>>();
463 Array2D::from_column_major(&array_column_major, num_rows, num_columns)
464 .expect("Filled by should never fail")
465 }
466
467 /// Creates a new [`Array2D`] with the specified number of rows and columns
468 /// and fills each element with the elements produced from the provided
469 /// iterator. If the iterator produces more than enough elements, the
470 /// remaining are unused. Returns an error if the iterator does not produce
471 /// enough elements.
472 ///
473 /// The elements are inserted into the array in [row major order].
474 ///
475 /// # Examples
476 ///
477 /// ```
478 /// # use array2d::{Array2D, Error};
479 /// # fn main() -> Result<(), Error> {
480 /// let iterator = (1..);
481 /// let array = Array2D::from_iter_row_major(iterator, 2, 3)?;
482 /// assert_eq!(array.as_rows(), vec![vec![1, 2, 3], vec![4, 5, 6]]);
483 /// # Ok(())
484 /// # }
485 /// ```
486 ///
487 /// [`Array2D`]: struct.Array2D.html
488 /// [row major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
489 pub fn from_iter_row_major<I>(
490 iterator: I,
491 num_rows: usize,
492 num_columns: usize,
493 ) -> Result<Self, Error>
494 where
495 I: Iterator<Item = T>,
496 {
497 let total_len = num_rows * num_columns;
498 let array = iterator.take(total_len).collect::<Vec<_>>();
499 if array.len() != total_len {
500 return Err(Error::NotEnoughElements);
501 }
502 Ok(Array2D {
503 array,
504 num_rows,
505 num_columns,
506 })
507 }
508
509 /// Creates a new [`Array2D`] with the specified number of rows and columns
510 /// and fills each element with the elements produced from the provided
511 /// iterator. If the iterator produces more than enough elements, the
512 /// remaining are unused. Returns an error if the iterator does not produce
513 /// enough elements.
514 ///
515 /// The elements are inserted into the array in [column major order].
516 ///
517 /// # Examples
518 ///
519 /// ```
520 /// # use array2d::{Array2D, Error};
521 /// # fn main() -> Result<(), Error> {
522 /// let iterator = (1..);
523 /// let array = Array2D::from_iter_column_major(iterator, 2, 3)?;
524 /// assert_eq!(array.as_rows(), vec![vec![1, 3, 5], vec![2, 4, 6]]);
525 /// # Ok(())
526 /// # }
527 /// ```
528 ///
529 /// [`Array2D`]: struct.Array2D.html
530 /// [column major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
531 pub fn from_iter_column_major<I>(
532 iterator: I,
533 num_rows: usize,
534 num_columns: usize,
535 ) -> Result<Self, Error>
536 where
537 I: Iterator<Item = T>,
538 T: Clone,
539 {
540 let total_len = num_rows * num_columns;
541 let array_column_major = iterator.take(total_len).collect::<Vec<_>>();
542 Array2D::from_column_major(&array_column_major, num_rows, num_columns)
543 .map_err(|_| Error::NotEnoughElements)
544 }
545
546 /// The number of rows.
547 pub fn num_rows(&self) -> usize {
548 self.num_rows
549 }
550
551 /// The number of columns.
552 pub fn num_columns(&self) -> usize {
553 self.num_columns
554 }
555
556 /// The total number of elements, i.e. the product of `num_rows` and
557 /// `num_columns`.
558 pub fn num_elements(&self) -> usize {
559 self.num_rows * self.num_columns
560 }
561
562 /// The number of elements in each row, i.e. the number of columns.
563 pub fn row_len(&self) -> usize {
564 self.num_columns
565 }
566
567 /// The number of elements in each column, i.e. the number of rows.
568 pub fn column_len(&self) -> usize {
569 self.num_rows
570 }
571
572 /// Returns a reference to the element at the given `row` and `column` if the
573 /// index is in bounds (wrapped in [`Some`]). Returns [`None`] if the index
574 /// is out of bounds.
575 ///
576 /// # Examples
577 ///
578 /// ```
579 /// # use array2d::{Array2D, Error};
580 /// let array = Array2D::filled_with(42, 2, 3);
581 /// assert_eq!(array.get(0, 0), Some(&42));
582 /// assert_eq!(array.get(10, 10), None);
583 /// ```
584 ///
585 /// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
586 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
587 pub fn get(&self, row: usize, column: usize) -> Option<&T> {
588 self.get_index(row, column).map(|index| &self.array[index])
589 }
590
591 /// Returns a reference to the element at the given index in row major
592 /// order. Returns [`None`] if the index is out of bounds.
593 ///
594 /// # Examples
595 ///
596 /// ```
597 /// # use array2d::{Array2D, Error};
598 /// # fn main() -> Result<(), Error> {
599 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
600 /// let array = Array2D::from_rows(&rows)?;
601 /// assert_eq!(array.get_row_major(2), Some(&3));
602 /// assert_eq!(array.get_row_major(4), Some(&5));
603 /// assert_eq!(array.get_row_major(10), None);
604 /// # Ok(())
605 /// # }
606 /// ```
607 ///
608 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
609 pub fn get_row_major(&self, index: usize) -> Option<&T> {
610 self.array.get(index)
611 }
612
613 /// Returns a reference to the element at the given index in column major
614 /// order. Returns [`None`] if the index is out of bounds.
615 ///
616 /// # Examples
617 ///
618 /// ```
619 /// # use array2d::{Array2D, Error};
620 /// # fn main() -> Result<(), Error> {
621 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
622 /// let array = Array2D::from_rows(&rows)?;
623 /// assert_eq!(array.get_column_major(2), Some(&2));
624 /// assert_eq!(array.get_column_major(4), Some(&3));
625 /// assert_eq!(array.get_column_major(10), None);
626 /// # Ok(())
627 /// # }
628 /// ```
629 ///
630 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
631 pub fn get_column_major(&self, index: usize) -> Option<&T> {
632 let column = dbg!(dbg!(index) / self.num_rows);
633 let row = dbg!(index % self.num_rows);
634 self.get(row, column)
635 }
636
637 /// Returns a mutable reference to the element at the given `row` and
638 /// `column` if the index is in bounds (wrapped in [`Some`]). Returns
639 /// [`None`] if the index is out of bounds.
640 ///
641 /// # Examples
642 ///
643 /// ```
644 /// # use array2d::{Array2D, Error};
645 /// let mut array = Array2D::filled_with(42, 2, 3);
646 ///
647 /// assert_eq!(array.get_mut(0, 0), Some(&mut 42));
648 /// assert_eq!(array.get_mut(10, 10), None);
649 ///
650 /// array.get_mut(0, 0).map(|x| *x = 100);
651 /// assert_eq!(array.get(0, 0), Some(&100));
652 ///
653 /// array.get_mut(10, 10).map(|x| *x = 200);
654 /// assert_eq!(array.get(10, 10), None);
655 /// ```
656 ///
657 /// [`Some`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
658 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
659 pub fn get_mut(&mut self, row: usize, column: usize) -> Option<&mut T> {
660 self.get_index(row, column)
661 .map(move |index| &mut self.array[index])
662 }
663
664 /// Returns a mutable reference to the element at the given index in row
665 /// major order. Returns [`None`] if the index is out of bounds.
666 ///
667 /// # Examples
668 ///
669 /// ```
670 /// # use array2d::{Array2D, Error};
671 /// # fn main() -> Result<(), Error> {
672 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
673 /// let mut array = Array2D::from_rows(&rows)?;
674 ///
675 /// assert_eq!(array.get_mut_row_major(1), Some(&mut 2));
676 /// assert_eq!(array.get_mut_row_major(10), None);
677 ///
678 /// array.get_mut_row_major(3).map(|x| *x = 100);
679 /// assert_eq!(array.get(1, 0), Some(&100));
680 ///
681 /// array.get_mut_row_major(10).map(|x| *x = 200);
682 /// assert_eq!(array.get(10, 10), None);
683 /// # Ok(())
684 /// # }
685 /// ```
686 ///
687 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
688 pub fn get_mut_row_major(&mut self, index: usize) -> Option<&mut T> {
689 self.array.get_mut(index)
690 }
691
692 /// Returns a mutable reference to the element at the given index in row
693 /// major order. Returns [`None`] if the index is out of bounds.
694 ///
695 /// # Examples
696 ///
697 /// ```
698 /// # use array2d::{Array2D, Error};
699 /// # fn main() -> Result<(), Error> {
700 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
701 /// let mut array = Array2D::from_rows(&rows)?;
702 ///
703 /// assert_eq!(array.get_mut_column_major(1), Some(&mut 4));
704 /// assert_eq!(array.get_mut_column_major(10), None);
705 ///
706 /// array.get_mut_column_major(4).map(|x| *x = 100);
707 /// assert_eq!(array.get(0, 2), Some(&100));
708 ///
709 /// array.get_mut_column_major(10).map(|x| *x = 200);
710 /// assert_eq!(array.get(10, 10), None);
711 /// # Ok(())
712 /// # }
713 /// ```
714 ///
715 /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
716 pub fn get_mut_column_major(&mut self, index: usize) -> Option<&mut T> {
717 let column = index / self.num_rows;
718 let row = index % self.num_rows;
719 self.get_mut(row, column)
720 }
721
722 /// Changes the element at given `row` and `column` to `element`. Returns
723 /// [`Ok(())`] if the indices were in bounds and returns an [`Err`]
724 /// otherwise.
725 ///
726 /// # Examples
727 ///
728 /// ```
729 /// # use array2d::{Array2D, Error};
730 /// let mut array = Array2D::filled_with(42, 2, 3);
731 ///
732 /// let result = array.set(0, 0, 100);
733 /// assert_eq!(result, Ok(()));
734 /// assert_eq!(array.get(0, 0), Some(&100));
735 ///
736 /// let result = array.set(10, 20, 200);
737 /// assert_eq!(result, Err(Error::IndicesOutOfBounds(10, 20)));
738 /// ```
739 ///
740 /// [`Ok(())`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok
741 /// [array2d::Error]: enum.Error.html
742 /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
743 /// [`array2d::Error`]: enum.Error.html
744 pub fn set(&mut self, row: usize, column: usize, element: T) -> Result<(), Error> {
745 self.get_mut(row, column)
746 .map(|location| {
747 *location = element;
748 })
749 .ok_or(Error::IndicesOutOfBounds(row, column))
750 }
751
752 /// Changes the element at the given `index` to `element`, in row major
753 /// order. Returns [`Ok(())`] if the index is in bounds and returns an
754 /// [`Err`] otherwise.
755 ///
756 /// # Examples
757 ///
758 /// ```
759 /// # use array2d::{Array2D, Error};
760 /// let mut array = Array2D::filled_with(42, 2, 3);
761 ///
762 /// let result = array.set_row_major(4, 100);
763 /// assert_eq!(result, Ok(()));
764 /// assert_eq!(array.get(1, 1), Some(&100));
765 ///
766 /// let result = array.set_row_major(10, 200);
767 /// assert_eq!(result, Err(Error::IndexOutOfBounds(10)));
768 /// ```
769 ///
770 /// [`Ok(())`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok
771 /// [array2d::Error]: enum.Error.html
772 /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
773 /// [`array2d::Error`]: enum.Error.html
774 pub fn set_row_major(&mut self, index: usize, element: T) -> Result<(), Error> {
775 self.get_mut_row_major(index)
776 .map(|location| {
777 *location = element;
778 })
779 .ok_or(Error::IndexOutOfBounds(index))
780 }
781
782 /// Changes the element at the given `index` to `element`, in column major
783 /// order. Returns [`Ok(())`] if the index is in bounds and returns an
784 /// [`Err`] otherwise.
785 ///
786 /// # Examples
787 ///
788 /// ```
789 /// # use array2d::{Array2D, Error};
790 /// let mut array = Array2D::filled_with(42, 2, 3);
791 ///
792 /// let result = array.set_column_major(4, 100);
793 /// assert_eq!(result, Ok(()));
794 /// assert_eq!(array.get(0, 2), Some(&100));
795 ///
796 /// let result = array.set_column_major(10, 200);
797 /// assert_eq!(result, Err(Error::IndexOutOfBounds(10)));
798 /// ```
799 ///
800 /// [`Ok(())`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok
801 /// [array2d::Error]: enum.Error.html
802 /// [`Err`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
803 /// [`array2d::Error`]: enum.Error.html
804 pub fn set_column_major(&mut self, index: usize, element: T) -> Result<(), Error> {
805 self.get_mut_column_major(index)
806 .map(|location| {
807 *location = element;
808 })
809 .ok_or(Error::IndexOutOfBounds(index))
810 }
811
812 /// Returns an [`Iterator`] over references to all elements in [row major
813 /// order].
814 ///
815 /// # Examples
816 ///
817 /// ```
818 /// # use array2d::{Array2D, Error};
819 /// # fn main() -> Result<(), Error> {
820 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
821 /// let elements = vec![1, 2, 3, 4, 5, 6];
822 /// let array = Array2D::from_rows(&rows)?;
823 /// let row_major = array.elements_row_major_iter();
824 /// assert_eq!(row_major.cloned().collect::<Vec<_>>(), elements);
825 /// # Ok(())
826 /// # }
827 /// ```
828 ///
829 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
830 /// [row major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
831 pub fn elements_row_major_iter(&self) -> impl DoubleEndedIterator<Item = &T> + Clone {
832 self.array.iter()
833 }
834
835 /// Returns an [`Iterator`] over references to all elements in [column major
836 /// order].
837 ///
838 /// # Examples
839 ///
840 /// ```
841 /// # use array2d::{Array2D, Error};
842 /// # fn main() -> Result<(), Error> {
843 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
844 /// let elements = vec![1, 4, 2, 5, 3, 6];
845 /// let array = Array2D::from_rows(&rows)?;
846 /// let column_major = array.elements_column_major_iter();
847 /// assert_eq!(column_major.cloned().collect::<Vec<_>>(), elements);
848 /// # Ok(())
849 /// # }
850 /// ```
851 ///
852 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
853 /// [column major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
854 pub fn elements_column_major_iter(&self) -> impl DoubleEndedIterator<Item = &T> + Clone {
855 self.indices_column_major().map(move |i| &self[i])
856 }
857
858 /// Returns an [`Iterator`] over references to all elements in the given
859 /// row. Returns an error if the index is out of bounds.
860 ///
861 /// # Examples
862 ///
863 /// ```
864 /// # use array2d::{Array2D, Error};
865 /// # fn main() -> Result<(), Error> {
866 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
867 /// let array = Array2D::from_rows(&rows)?;
868 /// let mut row_iter = array.row_iter(1)?;
869 /// assert_eq!(row_iter.next(), Some(&4));
870 /// assert_eq!(row_iter.next(), Some(&5));
871 /// assert_eq!(row_iter.next(), Some(&6));
872 /// assert_eq!(row_iter.next(), None);
873 /// # Ok(())
874 /// # }
875 /// ```
876 ///
877 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
878 pub fn row_iter(&self, row_index: usize) -> Result<impl DoubleEndedIterator<Item = &T> + Clone, Error> {
879 let start = self
880 .get_index(row_index, 0)
881 .ok_or(Error::IndicesOutOfBounds(row_index, 0))?;
882 let end = start + self.row_len();
883 Ok(self.array[start..end].iter())
884 }
885
886 /// Returns an [`Iterator`] over references to all elements in the given
887 /// column. Returns an error if the index is out of bounds.
888 ///
889 /// # Examples
890 ///
891 /// ```
892 /// # use array2d::{Array2D, Error};
893 /// # fn main() -> Result<(), Error> {
894 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
895 /// let array = Array2D::from_rows(&rows)?;
896 /// let mut column_iter = array.column_iter(1)?;
897 /// assert_eq!(column_iter.next(), Some(&2));
898 /// assert_eq!(column_iter.next(), Some(&5));
899 /// assert_eq!(column_iter.next(), None);
900 /// # Ok(())
901 /// # }
902 /// ```
903 ///
904 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
905 pub fn column_iter(
906 &self,
907 column_index: usize,
908 ) -> Result<impl DoubleEndedIterator<Item = &T> + Clone, Error> {
909 if column_index >= self.num_columns {
910 return Err(Error::IndicesOutOfBounds(0, column_index));
911 }
912 Ok((0..self.column_len()).map(move |row_index| &self[(row_index, column_index)]))
913 }
914
915 /// Returns an [`Iterator`] over all rows. Each [`Item`] is itself another
916 /// [`Iterator`] over references to the elements in that row.
917 ///
918 /// # Examples
919 ///
920 /// ```
921 /// # use array2d::{Array2D, Error};
922 /// # fn main() -> Result<(), Error> {
923 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
924 /// let array = Array2D::from_rows(&rows)?;
925 /// for row_iter in array.rows_iter() {
926 /// for element in row_iter {
927 /// print!("{} ", element);
928 /// }
929 /// println!();
930 /// }
931 ///
932 /// let mut rows_iter = array.rows_iter();
933 ///
934 /// let mut first_row_iter = rows_iter.next().unwrap();
935 /// assert_eq!(first_row_iter.next(), Some(&1));
936 /// assert_eq!(first_row_iter.next(), Some(&2));
937 /// assert_eq!(first_row_iter.next(), Some(&3));
938 /// assert_eq!(first_row_iter.next(), None);
939 ///
940 /// let mut second_row_iter = rows_iter.next().unwrap();
941 /// assert_eq!(second_row_iter.next(), Some(&4));
942 /// assert_eq!(second_row_iter.next(), Some(&5));
943 /// assert_eq!(second_row_iter.next(), Some(&6));
944 /// assert_eq!(second_row_iter.next(), None);
945 ///
946 /// assert!(rows_iter.next().is_none());
947 /// # Ok(())
948 /// # }
949 /// ```
950 ///
951 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
952 /// [`Item`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#associatedtype.Item
953 pub fn rows_iter(
954 &self,
955 ) -> impl DoubleEndedIterator<Item = impl DoubleEndedIterator<Item = &T> + Clone> + Clone {
956 (0..self.num_rows()).map(move |row_index| {
957 self.row_iter(row_index)
958 .expect("rows_iter should never fail")
959 })
960 }
961
962 /// Returns an [`Iterator`] over all columns. Each [`Item`] is itself
963 /// another [`Iterator`] over references to the elements in that column.
964 ///
965 /// # Examples
966 ///
967 /// ```
968 /// # use array2d::{Array2D, Error};
969 /// # fn main() -> Result<(), Error> {
970 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
971 /// let array = Array2D::from_rows(&rows)?;
972 /// for column_iter in array.columns_iter() {
973 /// for element in column_iter {
974 /// print!("{} ", element);
975 /// }
976 /// println!();
977 /// }
978 ///
979 /// let mut columns_iter = array.columns_iter();
980 ///
981 /// let mut first_column_iter = columns_iter.next().unwrap();
982 /// assert_eq!(first_column_iter.next(), Some(&1));
983 /// assert_eq!(first_column_iter.next(), Some(&4));
984 /// assert_eq!(first_column_iter.next(), None);
985 ///
986 /// let mut second_column_iter = columns_iter.next().unwrap();
987 /// assert_eq!(second_column_iter.next(), Some(&2));
988 /// assert_eq!(second_column_iter.next(), Some(&5));
989 /// assert_eq!(second_column_iter.next(), None);
990 ///
991 /// let mut third_column_iter = columns_iter.next().unwrap();
992 /// assert_eq!(third_column_iter.next(), Some(&3));
993 /// assert_eq!(third_column_iter.next(), Some(&6));
994 /// assert_eq!(third_column_iter.next(), None);
995 ///
996 /// assert!(columns_iter.next().is_none());
997 /// # Ok(())
998 /// # }
999 /// ```
1000 ///
1001 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
1002 /// [`Item`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#associatedtype.Item
1003 pub fn columns_iter(
1004 &self,
1005 ) -> impl DoubleEndedIterator<Item = impl DoubleEndedIterator<Item = &T> + Clone> + Clone {
1006 (0..self.num_columns).map(move |column_index| {
1007 self.column_iter(column_index)
1008 .expect("columns_iter should never fail")
1009 })
1010 }
1011
1012 /// Collects the [`Array2D`] into a [`Vec`] of rows, each of which contains
1013 /// a [`Vec`] of elements.
1014 ///
1015 /// # Examples
1016 ///
1017 /// ```
1018 /// # use array2d::{Array2D, Error};
1019 /// # fn main() -> Result<(), Error> {
1020 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1021 /// let array = Array2D::from_rows(&rows)?;
1022 /// assert_eq!(array.as_rows(), rows);
1023 /// # Ok(())
1024 /// # }
1025 /// ```
1026 ///
1027 /// [`Array2D`]: struct.Array2D.html
1028 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
1029 pub fn as_rows(&self) -> Vec<Vec<T>>
1030 where
1031 T: Clone,
1032 {
1033 self.rows_iter()
1034 .map(|row_iter| row_iter.cloned().collect())
1035 .collect()
1036 }
1037
1038 /// Collects the [`Array2D`] into a [`Vec`] of columns, each of which
1039 /// contains a [`Vec`] of elements.
1040 ///
1041 /// # Examples
1042 ///
1043 /// ```
1044 /// # use array2d::{Array2D, Error};
1045 /// # fn main() -> Result<(), Error> {
1046 /// let columns = vec![vec![1, 4], vec![2, 5], vec![3, 6]];
1047 /// let array = Array2D::from_columns(&columns)?;
1048 /// assert_eq!(array.as_columns(), columns);
1049 /// # Ok(())
1050 /// # }
1051 /// ```
1052 ///
1053 /// [`Array2D`]: struct.Array2D.html
1054 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
1055 pub fn as_columns(&self) -> Vec<Vec<T>>
1056 where
1057 T: Clone,
1058 {
1059 self.columns_iter()
1060 .map(|column_iter| column_iter.cloned().collect())
1061 .collect()
1062 }
1063
1064 /// Collects the [`Array2D`] into a [`Vec`] of elements in [row major
1065 /// order].
1066 ///
1067 /// # Examples
1068 ///
1069 /// ```
1070 /// # use array2d::{Array2D, Error};
1071 /// # fn main() -> Result<(), Error> {
1072 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1073 /// let array = Array2D::from_rows(&rows)?;
1074 /// assert_eq!(array.as_row_major(), vec![1, 2, 3, 4, 5, 6]);
1075 /// # Ok(())
1076 /// # }
1077 /// ```
1078 ///
1079 /// [`Array2D`]: struct.Array2D.html
1080 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
1081 /// [row major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
1082 pub fn as_row_major(&self) -> Vec<T>
1083 where
1084 T: Clone,
1085 {
1086 self.elements_row_major_iter().cloned().collect()
1087 }
1088
1089 /// Collects the [`Array2D`] into a [`Vec`] of elements in [column major
1090 /// order].
1091 ///
1092 /// # Examples
1093 ///
1094 /// ```
1095 /// # use array2d::{Array2D, Error};
1096 /// # fn main() -> Result<(), Error> {
1097 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1098 /// let array = Array2D::from_rows(&rows)?;
1099 /// assert_eq!(array.as_column_major(), vec![1, 4, 2, 5, 3, 6]);
1100 /// # Ok(())
1101 /// # }
1102 /// ```
1103 ///
1104 /// [`Array2D`]: struct.Array2D.html
1105 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
1106 /// [column major order]: https://en.wikipedia.org/wiki/Row-_and_column-major_order
1107 pub fn as_column_major(&self) -> Vec<T>
1108 where
1109 T: Clone,
1110 {
1111 self.elements_column_major_iter().cloned().collect()
1112 }
1113
1114 /// Returns the indices of the array in row major order. Each index is a tuple of [`usize`].
1115 ///
1116 /// # Examples
1117 ///
1118 /// ```
1119 /// # use array2d::{Array2D, Error};
1120 /// # fn main() -> Result<(), Error> {
1121 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1122 /// let array = Array2D::from_rows(&rows)?;
1123 /// let indices_row_major = array.indices_row_major().collect::<Vec<_>>();
1124 /// assert_eq!(
1125 /// indices_row_major,
1126 /// vec![(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
1127 /// );
1128 /// # Ok(())
1129 /// # }
1130 /// ```
1131 ///
1132 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
1133 pub fn indices_row_major(&self) -> impl DoubleEndedIterator<Item = (usize, usize)> + Clone {
1134 indices_row_major(self.num_rows, self.num_columns)
1135 }
1136
1137 /// Returns the indices of the array in column major order. Each index is a tuple of [`usize`].
1138 ///
1139 /// # Examples
1140 ///
1141 /// ```
1142 /// # use array2d::{Array2D, Error};
1143 /// # fn main() -> Result<(), Error> {
1144 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1145 /// let array = Array2D::from_rows(&rows)?;
1146 /// let indices_column_major = array.indices_column_major().collect::<Vec<_>>();
1147 /// assert_eq!(
1148 /// indices_column_major,
1149 /// vec![(0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2)]
1150 /// );
1151 /// # Ok(())
1152 /// # }
1153 /// ```
1154 ///
1155 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
1156 pub fn indices_column_major(&self) -> impl DoubleEndedIterator<Item = (usize, usize)> + Clone {
1157 indices_column_major(self.num_rows, self.num_columns)
1158 }
1159
1160 /// Iterate through the array in row major order along with the corresponding indices. Each
1161 /// index is a tuple of [`usize`].
1162 ///
1163 /// # Examples
1164 ///
1165 /// ```
1166 /// # use array2d::{Array2D, Error};
1167 /// # fn main() -> Result<(), Error> {
1168 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1169 /// let array = Array2D::from_rows(&rows)?;
1170 /// let enumerate_row_major = array.enumerate_row_major().collect::<Vec<_>>();
1171 /// assert_eq!(
1172 /// enumerate_row_major,
1173 /// vec![
1174 /// ((0, 0), &1),
1175 /// ((0, 1), &2),
1176 /// ((0, 2), &3),
1177 /// ((1, 0), &4),
1178 /// ((1, 1), &5),
1179 /// ((1, 2), &6)
1180 /// ]
1181 /// );
1182 /// # Ok(())
1183 /// # }
1184 /// ```
1185 ///
1186 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
1187 pub fn enumerate_row_major(
1188 &self,
1189 ) -> impl DoubleEndedIterator<Item = ((usize, usize), &T)> + Clone {
1190 self.indices_row_major().map(move |i| (i, &self[i]))
1191 }
1192
1193 /// Iterate through the array in column major order along with the corresponding indices. Each
1194 /// index is a tuple of [`usize`].
1195 ///
1196 /// # Examples
1197 ///
1198 /// ```
1199 /// # use array2d::{Array2D, Error};
1200 /// # fn main() -> Result<(), Error> {
1201 /// let rows = vec![vec![1, 2, 3], vec![4, 5, 6]];
1202 /// let array = Array2D::from_rows(&rows)?;
1203 /// let enumerate_column_major = array.enumerate_column_major().collect::<Vec<_>>();
1204 /// assert_eq!(
1205 /// enumerate_column_major,
1206 /// vec![
1207 /// ((0, 0), &1),
1208 /// ((1, 0), &4),
1209 /// ((0, 1), &2),
1210 /// ((1, 1), &5),
1211 /// ((0, 2), &3),
1212 /// ((1, 2), &6)
1213 /// ]
1214 /// );
1215 /// # Ok(())
1216 /// # }
1217 /// ```
1218 ///
1219 /// [`usize`]: https://doc.rust-lang.org/std/primitive.usize.html
1220 pub fn enumerate_column_major(
1221 &self,
1222 ) -> impl DoubleEndedIterator<Item = ((usize, usize), &T)> + Clone {
1223 self.indices_column_major().map(move |i| (i, &self[i]))
1224 }
1225
1226 fn get_index(&self, row: usize, column: usize) -> Option<usize> {
1227 if row < self.num_rows && column < self.num_columns {
1228 Some(row * self.row_len() + column)
1229 } else {
1230 None
1231 }
1232 }
1233}
1234
1235impl<T> Index<(usize, usize)> for Array2D<T> {
1236 type Output = T;
1237
1238 /// Returns the element at the given indices, given as `(row, column)`.
1239 ///
1240 /// # Examples
1241 ///
1242 /// ```
1243 /// # use array2d::{Array2D, Error};
1244 /// let array = Array2D::filled_with(42, 2, 3);
1245 /// assert_eq!(array[(0, 0)], 42);
1246 /// ```
1247 ///
1248 /// # Panics
1249 ///
1250 /// Panics if the indices are out of bounds.
1251 ///
1252 /// ```rust,should_panic
1253 /// # use array2d::Array2D;
1254 /// let array = Array2D::filled_with(42, 2, 3);
1255 /// let element = array[(10, 10)];
1256 /// ```
1257 fn index(&self, (row, column): (usize, usize)) -> &Self::Output {
1258 self.get(row, column)
1259 .unwrap_or_else(|| panic!("Index indices {}, {} out of bounds", row, column))
1260 }
1261}
1262
1263impl<T> IndexMut<(usize, usize)> for Array2D<T> {
1264 /// Returns a mutable version of the element at the given indices, given as
1265 /// `(row, column)`.
1266 ///
1267 /// # Examples
1268 ///
1269 /// ```
1270 /// # use array2d::{Array2D, Error};
1271 /// let mut array = Array2D::filled_with(42, 2, 3);
1272 /// array[(0, 0)] = 100;
1273 /// assert_eq!(array[(0, 0)], 100);
1274 /// ```
1275 ///
1276 /// # Panics
1277 ///
1278 /// Panics if the indices are out of bounds.
1279 ///
1280 /// ```rust,should_panic
1281 /// # use array2d::Array2D;
1282 /// let mut array = Array2D::filled_with(42, 2, 3);
1283 /// array[(10, 10)] = 7;
1284 /// ```
1285 fn index_mut(&mut self, (row, column): (usize, usize)) -> &mut Self::Output {
1286 self.get_mut(row, column)
1287 .unwrap_or_else(|| panic!("Index mut indices {}, {} out of bounds", row, column))
1288 }
1289}
1290
1291fn flatten<T: Clone>(nested: &[Vec<T>]) -> Vec<T> {
1292 nested.iter().flat_map(|row| row.clone()).collect()
1293}
1294
1295fn indices_row_major(
1296 num_rows: usize,
1297 num_columns: usize,
1298) -> impl DoubleEndedIterator<Item = (usize, usize)> + Clone {
1299 (0..num_rows).flat_map(move |row| (0..num_columns).map(move |column| (row, column)))
1300}
1301
1302fn indices_column_major(
1303 num_rows: usize,
1304 num_columns: usize,
1305) -> impl DoubleEndedIterator<Item = (usize, usize)> + Clone {
1306 (0..num_columns).flat_map(move |column| (0..num_rows).map(move |row| (row, column)))
1307}