Add multi_slice_* methods (supports nested tuples) by jturner314 · Pull Request #716 · rust-ndarray/ndarray · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/dimension/mod.rs
34 changes: 34 additions & 0 deletions src/impl_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::iter::{
AxisChunksIter, AxisChunksIterMut, AxisIter, AxisIterMut, ExactChunks, ExactChunksMut,
IndexedIter, IndexedIterMut, Iter, IterMut, Lanes, LanesMut, Windows,
};
use crate::slice::MultiSlice;
use crate::stacking::stack;
use crate::{NdIndex, Slice, SliceInfo, SliceOrIndex};

Expand Down Expand Up @@ -350,6 +351,39 @@ where
self.view_mut().slice_move(info)
}

/// Return multiple disjoint, sliced, mutable views of the array.
///
/// See [*Slicing*](#slicing) for full documentation.
/// See also [`SliceInfo`] and [`D::SliceArg`].
///
/// [`SliceInfo`]: struct.SliceInfo.html
/// [`D::SliceArg`]: trait.Dimension.html#associatedtype.SliceArg
///
/// **Panics** if any of the following occur:
///
/// * if any of the views would intersect (i.e. if any element would appear in multiple slices)
/// * if an index is out of bounds or step size is zero
/// * if `D` is `IxDyn` and `info` does not match the number of array axes
///
/// # Example
///
/// ```
/// use ndarray::{arr2, s};
///
/// let mut a = arr2(&[[1, 2, 3], [4, 5, 6]]);
/// let (mut edges, mut middle) = a.multi_slice_mut((s![.., ..;2], s![.., 1]));
/// edges.fill(1);
/// middle.fill(0);
/// assert_eq!(a, arr2(&[[1, 0, 1], [1, 0, 1]]));
/// ```
pub fn multi_slice_mut<'a, M>(&'a mut self, info: M) -> M::Output
where
M: MultiSlice<'a, A, D>,
S: DataMut,
{
unsafe { info.slice_and_deref(self.raw_view_mut()) }
}

/// Slice the array, possibly changing the number of dimensions.
///
/// See [*Slicing*](#slicing) for full documentation.
Expand Down
26 changes: 26 additions & 0 deletions src/impl_views/splitting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// except according to those terms.

use crate::imp_prelude::*;
use crate::slice::MultiSlice;

/// Methods for read-only array views.
impl<'a, A, D> ArrayView<'a, A, D>
Expand Down Expand Up @@ -109,4 +110,29 @@ where
(left.deref_into_view_mut(), right.deref_into_view_mut())
}
}

/// Split the view into multiple disjoint slices.
///
/// This is similar to [`.multi_slice_mut()`], but `.multi_slice_move()`
/// consumes `self` and produces views with lifetimes matching that of
/// `self`.
///
/// See [*Slicing*](#slicing) for full documentation.
/// See also [`SliceInfo`] and [`D::SliceArg`].
///
/// [`.multi_slice_mut()`]: struct.ArrayBase.html#method.multi_slice_mut
/// [`SliceInfo`]: struct.SliceInfo.html
/// [`D::SliceArg`]: trait.Dimension.html#associatedtype.SliceArg
///
/// **Panics** if any of the following occur:
///
/// * if any of the views would intersect (i.e. if any element would appear in multiple slices)
/// * if an index is out of bounds or step size is zero
/// * if `D` is `IxDyn` and `info` does not match the number of array axes
pub fn multi_slice_move<M>(mut self, info: M) -> M::Output
where
M: MultiSlice<'a, A, D>,
{
unsafe { info.slice_and_deref(self.raw_view_mut()) }
}
}
21 changes: 21 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,13 @@ pub type Ixs = isize;
/// [`.slice_move()`]: #method.slice_move
/// [`.slice_collapse()`]: #method.slice_collapse
///
/// It's possible to take multiple simultaneous *mutable* slices with the
/// [`.multi_slice_mut()`] or (for [`ArrayViewMut`] only)
/// [`.multi_slice_move()`].
///
/// [`.multi_slice_mut()`]: #method.multi_slice_mut
/// [`.multi_slice_move()`]: type.ArrayViewMut.html#method.multi_slice_move
///
/// ```
/// extern crate ndarray;
///
Expand Down Expand Up @@ -523,6 +530,20 @@ pub type Ixs = isize;
/// [12, 11, 10]]);
/// assert_eq!(f, g);
/// assert_eq!(f.shape(), &[2, 3]);
///
/// // Let's take two disjoint, mutable slices of a matrix with
/// //
/// // - One containing all the even-index columns in the matrix
/// // - One containing all the odd-index columns in the matrix
/// let mut h = arr2(&[[0, 1, 2, 3],
/// [4, 5, 6, 7]]);
/// let (s0, s1) = h.multi_slice_mut((s![.., ..;2], s![.., 1..;2]));
/// let i = arr2(&[[0, 2],
/// [4, 6]]);
/// let j = arr2(&[[1, 3],
/// [5, 7]]);
/// assert_eq!(s0, i);
/// assert_eq!(s1, j);
/// }
/// ```
///
Expand Down
189 changes: 188 additions & 1 deletion src/slice.rs
Loading