Skip to main content

ferray_ma/
filled.rs

1// ferray-ma: filled and compressed (REQ-5, REQ-6)
2
3use ferray_core::Array;
4use ferray_core::dimension::{Dimension, Ix1};
5use ferray_core::dtype::Element;
6use ferray_core::error::FerrayResult;
7
8use crate::MaskedArray;
9
10impl<T, D> MaskedArray<T, D>
11where
12    T: Element + Copy,
13    D: Dimension,
14{
15    /// Return a regular array with masked positions replaced by `fill_value`.
16    ///
17    /// Unmasked positions retain their original data values.
18    ///
19    /// # Errors
20    /// Returns an error only for internal failures.
21    pub fn filled(&self, fill_value: T) -> FerrayResult<Array<T, D>> {
22        let data: Vec<T> = self
23            .data()
24            .iter()
25            .zip(self.mask().iter())
26            .map(|(v, m)| if *m { fill_value } else { *v })
27            .collect();
28        Array::from_vec(self.dim().clone(), data)
29    }
30
31    /// Return a 1-D array containing only the unmasked elements.
32    ///
33    /// The order is the logical (row-major) iteration order of the
34    /// original array, with masked elements removed.
35    ///
36    /// # Errors
37    /// Returns an error only for internal failures.
38    pub fn compressed(&self) -> FerrayResult<Array<T, Ix1>> {
39        let data: Vec<T> = self
40            .data()
41            .iter()
42            .zip(self.mask().iter())
43            .filter(|(_, m)| !**m)
44            .map(|(v, _)| *v)
45            .collect();
46        let len = data.len();
47        Array::from_vec(Ix1::new([len]), data)
48    }
49}