A user on #rust-sci asked the best way to remove an element from an Array1. With current ndarray, if it's known to be contiguous (and with no extra elements in the Vec before/after the array data), probably the best way to do this is to convert to a Vec with .into_raw_vec(), remove the element with .remove(), and then convert the Vec back to an Array1. If the array is possibly discontiguous, it's simpler to allocate a new Array1 and copy the data into it with slicing and .assign().
It would be nice to provide a remove_index_axis method to provide this functionality for n-dimensional arrays.
Ideally, the implementation would reuse the existing allocation and just shift the existing elements.
-
For the "remove index along outermost axis for a contiguous array" special case, it would probably be best to use std::ptr::copy to shift the elements (i.e. implement it like Vec::remove). For Array, we'd need to be careful about how to drop the removed data and adjust the length of the underlying Vec. If we want to implement remove_index_axis for ArrayViewMut, we'd have to consider what to place in the last subview along the axis (before reducing the length of the axis in the view) so that we aren't illegally duplicating the elements in the last subview. If we want to move the removed data into that location, we'd need to store it in a temporary allocation before shifting the other elements with std::ptr::copy. We'd also need to be careful to avoid panics while in an invalid state.
-
For the general case, I'd suggest using something like accumulate_axis_inplace with Clone to copy the elements. In principle, we could implement the general case without Clone, but this would have the same safety challenges as using std::ptr::copy for the special case, while being more complex to implement.
For a first implementation, just implementing the general case would be useful, even if it isn't the most efficient approach in all cases.
A user on #rust-sci asked the best way to remove an element from an
Array1. With currentndarray, if it's known to be contiguous (and with no extra elements in theVecbefore/after the array data), probably the best way to do this is to convert to aVecwith.into_raw_vec(), remove the element with.remove(), and then convert theVecback to anArray1. If the array is possibly discontiguous, it's simpler to allocate a newArray1and copy the data into it with slicing and.assign().It would be nice to provide a
remove_index_axismethod to provide this functionality for n-dimensional arrays.Ideally, the implementation would reuse the existing allocation and just shift the existing elements.
For the "remove index along outermost axis for a contiguous array" special case, it would probably be best to use
std::ptr::copyto shift the elements (i.e. implement it likeVec::remove). ForArray, we'd need to be careful about how to drop the removed data and adjust the length of the underlyingVec. If we want to implementremove_index_axisforArrayViewMut, we'd have to consider what to place in the last subview along the axis (before reducing the length of the axis in the view) so that we aren't illegally duplicating the elements in the last subview. If we want to move the removed data into that location, we'd need to store it in a temporary allocation before shifting the other elements withstd::ptr::copy. We'd also need to be careful to avoid panics while in an invalid state.For the general case, I'd suggest using something like
accumulate_axis_inplacewithCloneto copy the elements. In principle, we could implement the general case withoutClone, but this would have the same safety challenges as usingstd::ptr::copyfor the special case, while being more complex to implement.For a first implementation, just implementing the general case would be useful, even if it isn't the most efficient approach in all cases.