1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use num_traits::PrimInt;
use vortex_dtype::{match_each_integer_ptype, match_each_native_ptype, NativePType};
use vortex_error::VortexResult;

use crate::array::primitive::PrimitiveArray;
use crate::compute::TakeFn;
use crate::{Array, IntoArray, IntoArrayVariant};

impl TakeFn for PrimitiveArray {
    fn take(&self, indices: &Array) -> VortexResult<Array> {
        let validity = self.validity();
        let indices = indices.clone().into_primitive()?;
        match_each_native_ptype!(self.ptype(), |$T| {
            match_each_integer_ptype!(indices.ptype(), |$I| {
                Ok(PrimitiveArray::from_vec(
                    take_primitive(self.maybe_null_slice::<$T>(), indices.maybe_null_slice::<$I>()),
                    validity.take(indices.array())?,
                ).into_array())
            })
        })
    }
}

fn take_primitive<T: NativePType, I: NativePType + PrimInt>(array: &[T], indices: &[I]) -> Vec<T> {
    indices
        .iter()
        .map(|&idx| array[idx.to_usize().unwrap()])
        .collect()
}

#[cfg(test)]
mod test {
    use crate::array::primitive::compute::take::take_primitive;

    #[test]
    fn test_take() {
        let a = vec![1i32, 2, 3, 4, 5];
        let result = take_primitive(&a, &[0, 0, 4, 2]);
        assert_eq!(result, vec![1i32, 1, 5, 3]);
    }
}