Skip to content

Commit cae2544

Browse files
committed
append: Add method .push() for appending an array with a dimension less.
1 parent 0386ef3 commit cae2544

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

src/impl_owned_array.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,66 @@ impl<A, D> Array<A, D>
278278
}
279279
}
280280

281+
/// Append an array to the array along an axis
282+
///
283+
/// Where the item to push to the array has one dimension less than the `self` array. This
284+
/// method is equivalent to `self.append(axis, array.insert_axis(axis))`.
285+
///
286+
/// The axis-to-append-to `axis` must be the array's "growing axis" for this operation
287+
/// to succeed. The growing axis is the outermost or last-visited when elements are visited in
288+
/// memory order:
289+
///
290+
/// `axis` must be the growing axis of the current array, an axis with length 0 or 1.
291+
///
292+
/// - This is the 0th axis for standard layout arrays
293+
/// - This is the *n*-1 th axis for fortran layout arrays
294+
/// - If the array is empty (the axis or any other has length 0) or if `axis`
295+
/// has length 1, then the array can always be appended.
296+
///
297+
/// ***Errors*** with a shape error if the shape of self does not match the array-to-append;
298+
/// all axes *except* the axis along which it being appended matter for this check.
299+
///
300+
/// The memory layout of the `self` array matters for ensuring that the append is efficient.
301+
/// Appending automatically changes memory layout of the array so that it is appended to
302+
/// along the "growing axis".
303+
///
304+
/// Ensure appending is efficient by for example starting from an empty array and/or always
305+
/// appending to an array along the same axis.
306+
///
307+
/// The amortized average complexity of the append, when appending along its growing axis, is
308+
/// O(*m*) where *m* is the length of the row.
309+
///
310+
/// The memory layout of the argument `array` does not matter to the same extent.
311+
///
312+
/// ```rust
313+
/// use ndarray::{Array, ArrayView, array, Axis};
314+
///
315+
/// // create an empty array and push rows to it
316+
/// let mut a = Array::zeros((0, 4));
317+
/// let ones = ArrayView::from(&[1.; 4]);
318+
/// let zeros = ArrayView::from(&[0.; 4]);
319+
/// a.push(Axis(0), ones).unwrap();
320+
/// a.push(Axis(0), zeros).unwrap();
321+
/// a.push(Axis(0), ones).unwrap();
322+
///
323+
/// assert_eq!(
324+
/// a,
325+
/// array![[1., 1., 1., 1.],
326+
/// [0., 0., 0., 0.],
327+
/// [1., 1., 1., 1.]]);
328+
/// ```
329+
pub fn push(&mut self, axis: Axis, array: ArrayView<A, D::Smaller>)
330+
-> Result<(), ShapeError>
331+
where
332+
A: Clone,
333+
D: RemoveAxis,
334+
{
335+
// same-dimensionality conversion
336+
self.append(axis, array.insert_axis(axis).into_dimensionality::<D>().unwrap())
337+
}
338+
281339

282-
/// Append an array to the array
340+
/// Append an array to the array along an axis
283341
///
284342
/// The axis-to-append-to `axis` must be the array's "growing axis" for this operation
285343
/// to succeed. The growing axis is the outermost or last-visited when elements are visited in

tests/append.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,28 @@ fn push_row_ignore_strides_length_one_axes() {
376376
}
377377
}
378378
}
379+
380+
#[test]
381+
#[should_panic(expected = "IncompatibleShape")]
382+
fn zero_dimensional_error1() {
383+
let mut a = Array::zeros(()).into_dyn();
384+
a.append(Axis(0), arr0(0).into_dyn().view()).unwrap();
385+
}
386+
387+
#[test]
388+
#[should_panic(expected = "IncompatibleShape")]
389+
fn zero_dimensional_error2() {
390+
let mut a = Array::zeros(()).into_dyn();
391+
a.push(Axis(0), arr0(0).into_dyn().view()).unwrap();
392+
}
393+
394+
#[test]
395+
fn zero_dimensional_ok() {
396+
let mut a = Array::zeros(0);
397+
let one = aview0(&1);
398+
let two = aview0(&2);
399+
a.push(Axis(0), two).unwrap();
400+
a.push(Axis(0), one).unwrap();
401+
a.push(Axis(0), one).unwrap();
402+
assert_eq!(a, array![2, 1, 1]);
403+
}

0 commit comments

Comments
 (0)