Skip to content

Commit 1500c9b

Browse files
authored
feat: add take for MapArray (#3925)
* feat: add take for MapArray * refactor: use into_builder
1 parent 71ecc39 commit 1500c9b

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

arrow-array/src/array/map_array.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// under the License.
1717

1818
use crate::array::{get_offsets, print_long_array};
19-
use crate::{make_array, Array, ArrayRef, StringArray, StructArray};
19+
use crate::{make_array, Array, ArrayRef, ListArray, StringArray, StructArray};
2020
use arrow_buffer::{ArrowNativeType, Buffer, NullBuffer, OffsetBuffer, ToByteSlice};
2121
use arrow_data::ArrayData;
2222
use arrow_schema::{ArrowError, DataType, Field};
@@ -251,6 +251,20 @@ impl std::fmt::Debug for MapArray {
251251
}
252252
}
253253

254+
impl From<MapArray> for ListArray {
255+
fn from(value: MapArray) -> Self {
256+
let field = match value.data_type() {
257+
DataType::Map(field, _) => field,
258+
_ => unreachable!("This should be a map type."),
259+
};
260+
let data_type = DataType::List(field.clone());
261+
let builder = value.into_data().into_builder().data_type(data_type);
262+
let array_data = unsafe { builder.build_unchecked() };
263+
264+
ListArray::from(array_data)
265+
}
266+
}
267+
254268
#[cfg(test)]
255269
mod tests {
256270
use crate::cast::AsArray;

arrow-select/src/take.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ where
150150
*length as u32,
151151
)?))
152152
}
153+
DataType::Map(_, _) => {
154+
let list_arr = ListArray::from(values.as_map().clone());
155+
let list_data = take_list::<_, Int32Type>(&list_arr, indices)?;
156+
let builder = list_data.into_data().into_builder().data_type(values.data_type().clone());
157+
Ok(Arc::new(MapArray::from(unsafe { builder.build_unchecked() })))
158+
}
153159
DataType::Struct(fields) => {
154160
let struct_: &StructArray =
155161
values.as_any().downcast_ref::<StructArray>().unwrap();
@@ -1919,6 +1925,30 @@ mod tests {
19191925
take(&list_array, &index, None).unwrap();
19201926
}
19211927

1928+
#[test]
1929+
fn test_take_map() {
1930+
let values = Int32Array::from(vec![1, 2, 3, 4]);
1931+
let array = MapArray::new_from_strings(
1932+
vec!["a", "b", "c", "a"].into_iter(),
1933+
&values,
1934+
&[0, 3, 4],
1935+
)
1936+
.unwrap();
1937+
1938+
let index = UInt32Array::from(vec![0]);
1939+
1940+
let result = take(&array, &index, None).unwrap();
1941+
let expected: ArrayRef = Arc::new(
1942+
MapArray::new_from_strings(
1943+
vec!["a", "b", "c"].into_iter(),
1944+
&values.slice(0, 3),
1945+
&[0, 3],
1946+
)
1947+
.unwrap(),
1948+
);
1949+
assert_eq!(&expected, &result);
1950+
}
1951+
19221952
#[test]
19231953
fn test_take_struct() {
19241954
let array = create_test_struct(vec![

0 commit comments

Comments
 (0)