Skip to content

Commit 0f55b82

Browse files
authored
window::shift to work for all array types (#388)
* add more doc test for window::shift * use Ok(make_array(array.data_ref().clone())) * shift array for not only primitive cases * include more test cases * add back copied * fix renaming
1 parent 0cbf85a commit 0f55b82

File tree

1 file changed

+53
-12
lines changed

1 file changed

+53
-12
lines changed

arrow/src/compute/kernels/window.rs

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! Defines windowing functions, like `shift`ing
1919
2020
use crate::array::{Array, ArrayRef};
21-
use crate::{array::PrimitiveArray, datatypes::ArrowPrimitiveType, error::Result};
21+
use crate::error::Result;
2222
use crate::{
2323
array::{make_array, new_null_array},
2424
compute::concat,
@@ -56,23 +56,20 @@ use num::{abs, clamp};
5656
/// let expected: Int32Array = vec![None, None, None].into();
5757
/// assert_eq!(res.as_ref(), &expected);
5858
/// ```
59-
pub fn shift<T>(values: &PrimitiveArray<T>, offset: i64) -> Result<ArrayRef>
60-
where
61-
T: ArrowPrimitiveType,
62-
{
63-
let value_len = values.len() as i64;
59+
pub fn shift(array: &Array, offset: i64) -> Result<ArrayRef> {
60+
let value_len = array.len() as i64;
6461
if offset == 0 {
65-
Ok(make_array(values.data_ref().clone()))
62+
Ok(make_array(array.data_ref().clone()))
6663
} else if offset == i64::MIN || abs(offset) >= value_len {
67-
Ok(new_null_array(&T::DATA_TYPE, values.len()))
64+
Ok(new_null_array(array.data_type(), array.len()))
6865
} else {
6966
let slice_offset = clamp(-offset, 0, value_len) as usize;
70-
let length = values.len() - abs(offset) as usize;
71-
let slice = values.slice(slice_offset, length);
67+
let length = array.len() - abs(offset) as usize;
68+
let slice = array.slice(slice_offset, length);
7269

7370
// Generate array with remaining `null` items
7471
let nulls = abs(offset) as usize;
75-
let null_arr = new_null_array(&T::DATA_TYPE, nulls);
72+
let null_arr = new_null_array(array.data_type(), nulls);
7673

7774
// Concatenate both arrays, add nulls after if shift > 0 else before
7875
if offset > 0 {
@@ -86,7 +83,7 @@ where
8683
#[cfg(test)]
8784
mod tests {
8885
use super::*;
89-
use crate::array::Int32Array;
86+
use crate::array::{Float64Array, Int32Array, Int32DictionaryArray};
9087

9188
#[test]
9289
fn test_shift_neg() {
@@ -104,6 +101,50 @@ mod tests {
104101
assert_eq!(res.as_ref(), &expected);
105102
}
106103

104+
#[test]
105+
fn test_shift_neg_float64() {
106+
let a: Float64Array = vec![Some(1.), None, Some(4.)].into();
107+
let res = shift(&a, -1).unwrap();
108+
let expected: Float64Array = vec![None, Some(4.), None].into();
109+
assert_eq!(res.as_ref(), &expected);
110+
}
111+
112+
#[test]
113+
fn test_shift_pos_float64() {
114+
let a: Float64Array = vec![Some(1.), None, Some(4.)].into();
115+
let res = shift(&a, 1).unwrap();
116+
let expected: Float64Array = vec![None, Some(1.), None].into();
117+
assert_eq!(res.as_ref(), &expected);
118+
}
119+
120+
#[test]
121+
fn test_shift_neg_int32_dict() {
122+
let a: Int32DictionaryArray = [Some("alpha"), None, Some("beta"), Some("alpha")]
123+
.iter()
124+
.copied()
125+
.collect();
126+
let res = shift(&a, -1).unwrap();
127+
let expected: Int32DictionaryArray = [None, Some("beta"), Some("alpha"), None]
128+
.iter()
129+
.copied()
130+
.collect();
131+
assert_eq!(res.as_ref(), &expected);
132+
}
133+
134+
#[test]
135+
fn test_shift_pos_int32_dict() {
136+
let a: Int32DictionaryArray = [Some("alpha"), None, Some("beta"), Some("alpha")]
137+
.iter()
138+
.copied()
139+
.collect();
140+
let res = shift(&a, 1).unwrap();
141+
let expected: Int32DictionaryArray = [None, Some("alpha"), None, Some("beta")]
142+
.iter()
143+
.copied()
144+
.collect();
145+
assert_eq!(res.as_ref(), &expected);
146+
}
147+
107148
#[test]
108149
fn test_shift_nil() {
109150
let a: Int32Array = vec![Some(1), None, Some(4)].into();

0 commit comments

Comments
 (0)