Skip to content

Commit d52e432

Browse files
committed
Add mapv, mapv_into, apply, applyv, visit
1 parent 46bb9d0 commit d52e432

File tree

1 file changed

+103
-2
lines changed

1 file changed

+103
-2
lines changed

src/impl_methods.rs

+103-2
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,10 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
10951095
init
10961096
}
10971097

1098-
/// Apply `f` elementwise and return a new array with
1099-
/// the results.
1098+
/// Call `f` by reference on each element and create a new array
1099+
/// with the results.
1100+
///
1101+
/// Elements are visited in arbitrary order.
11001102
///
11011103
/// Return an array with the same shape as *self*.
11021104
///
@@ -1128,4 +1130,103 @@ impl<A, S, D> ArrayBase<S, D> where S: Data<Elem=A>, D: Dimension
11281130
}
11291131
}
11301132
}
1133+
1134+
/// Call `f` by value on each element and create a new array
1135+
/// with the new values.
1136+
///
1137+
/// Elements are visited in arbitrary order.
1138+
///
1139+
/// Return an array with the same shape as *self*.
1140+
///
1141+
/// ```
1142+
/// use ndarray::arr2;
1143+
///
1144+
/// let a = arr2(&[[ 0., 1.],
1145+
/// [-1., 2.]]);
1146+
/// assert!(
1147+
/// a.mapv(f32::abs) == arr2(&[[0., 1.],
1148+
/// [1., 2.]])
1149+
/// );
1150+
/// ```
1151+
pub fn mapv<B, F>(&self, mut f: F) -> OwnedArray<B, D>
1152+
where F: FnMut(A) -> B,
1153+
A: Clone,
1154+
{
1155+
self.map(move |x| f(x.clone()))
1156+
}
1157+
1158+
/// Call `f` by value on each element, update the array with new values
1159+
/// and return it.
1160+
///
1161+
/// Elements are visited in arbitrary order.
1162+
pub fn mapv_into<F>(mut self, f: F) -> Self
1163+
where S: DataMut,
1164+
F: FnMut(A) -> A,
1165+
A: Clone,
1166+
{
1167+
self.applyv(f);
1168+
self
1169+
}
1170+
1171+
/// Modify in place by calling `f` by mutable reference on each element.
1172+
///
1173+
/// Elements are visited in arbitrary order.
1174+
pub fn apply<F>(&mut self, f: F)
1175+
where S: DataMut,
1176+
F: FnMut(&mut A),
1177+
{
1178+
self.unordered_foreach_mut(f);
1179+
}
1180+
1181+
/// Modify in place by calling `f` by value on each element. The
1182+
/// array is updated with the new values.
1183+
///
1184+
/// Elements are visited in arbitrary order.
1185+
///
1186+
/// ```
1187+
/// use ndarray::arr2;
1188+
///
1189+
/// let mut a = arr2(&[[ 0., 1.],
1190+
/// [-1., 2.]]);
1191+
/// a.applyv(f32::exp);
1192+
/// assert!(
1193+
/// a.allclose(&arr2(&[[1.00000, 2.71828],
1194+
/// [0.36788, 7.38906]]), 1e-5)
1195+
/// );
1196+
/// ```
1197+
pub fn applyv<F>(&mut self, mut f: F)
1198+
where S: DataMut,
1199+
F: FnMut(A) -> A,
1200+
A: Clone,
1201+
{
1202+
self.unordered_foreach_mut(move |x| *x = f(x.clone()));
1203+
}
1204+
1205+
/// Visit each element in the array by calling `f` by reference
1206+
/// on each element.
1207+
///
1208+
/// Elements are visited in arbitrary order.
1209+
pub fn visit<'a, F>(&'a self, mut f: F)
1210+
where F: FnMut(&'a A),
1211+
A: 'a,
1212+
{
1213+
if let Some(slc) = self.as_slice_memory_order() {
1214+
// FIXME: Use for loop when slice iterator is perf is restored
1215+
for i in 0..slc.len() {
1216+
f(&slc[i]);
1217+
}
1218+
} else {
1219+
for row in self.inner_iter() {
1220+
if let Some(slc) = row.into_slice() {
1221+
for i in 0..slc.len() {
1222+
f(&slc[i]);
1223+
}
1224+
} else {
1225+
for elt in row {
1226+
f(elt);
1227+
}
1228+
}
1229+
}
1230+
}
1231+
}
11311232
}

0 commit comments

Comments
 (0)