@@ -23,8 +23,12 @@ use std::ops::Add;
2323use std:: sync:: Arc ;
2424
2525use crate :: array:: { make_array, print_long_array} ;
26+ use crate :: builder:: { GenericListViewBuilder , PrimitiveBuilder } ;
2627use crate :: iterator:: GenericListViewArrayIter ;
27- use crate :: { Array , ArrayAccessor , ArrayRef , FixedSizeListArray , OffsetSizeTrait , new_empty_array} ;
28+ use crate :: {
29+ Array , ArrayAccessor , ArrayRef , ArrowPrimitiveType , FixedSizeListArray , OffsetSizeTrait ,
30+ new_empty_array,
31+ } ;
2832
2933/// A [`GenericListViewArray`] of variable size lists, storing offsets as `i32`.
3034pub type ListViewArray = GenericListViewArray < i32 > ;
@@ -357,6 +361,46 @@ impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
357361 value_sizes : self . value_sizes . slice ( offset, length) ,
358362 }
359363 }
364+
365+ /// Creates a [`GenericListViewArray`] from an iterator of primitive values
366+ /// # Example
367+ /// ```
368+ /// # use arrow_array::ListViewArray;
369+ /// # use arrow_array::types::Int32Type;
370+ ///
371+ /// let data = vec![
372+ /// Some(vec![Some(0), Some(1), Some(2)]),
373+ /// None,
374+ /// Some(vec![Some(3), None, Some(5)]),
375+ /// Some(vec![Some(6), Some(7)]),
376+ /// ];
377+ /// let list_array = ListViewArray::from_iter_primitive::<Int32Type, _, _>(data);
378+ /// println!("{:?}", list_array);
379+ /// ```
380+ pub fn from_iter_primitive < T , P , I > ( iter : I ) -> Self
381+ where
382+ T : ArrowPrimitiveType ,
383+ P : IntoIterator < Item = Option < <T as ArrowPrimitiveType >:: Native > > ,
384+ I : IntoIterator < Item = Option < P > > ,
385+ {
386+ let iter = iter. into_iter ( ) ;
387+ let size_hint = iter. size_hint ( ) . 0 ;
388+ let mut builder =
389+ GenericListViewBuilder :: with_capacity ( PrimitiveBuilder :: < T > :: new ( ) , size_hint) ;
390+
391+ for i in iter {
392+ match i {
393+ Some ( p) => {
394+ for t in p {
395+ builder. values ( ) . append_option ( t) ;
396+ }
397+ builder. append ( true ) ;
398+ }
399+ None => builder. append ( false ) ,
400+ }
401+ }
402+ builder. finish ( )
403+ }
360404}
361405
362406impl < OffsetSize : OffsetSizeTrait > ArrayAccessor for & GenericListViewArray < OffsetSize > {
@@ -559,7 +603,7 @@ impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
559603
560604#[ cfg( test) ]
561605mod tests {
562- use arrow_buffer:: { BooleanBuffer , Buffer , ScalarBuffer , bit_util} ;
606+ use arrow_buffer:: { BooleanBuffer , Buffer , NullBufferBuilder , ScalarBuffer , bit_util} ;
563607 use arrow_schema:: Field ;
564608
565609 use crate :: builder:: { FixedSizeListBuilder , Int32Builder } ;
@@ -1127,4 +1171,29 @@ mod tests {
11271171 let array = ListViewArray :: new_null ( field, 5 ) ;
11281172 assert_eq ! ( array. len( ) , 5 ) ;
11291173 }
1174+
1175+ #[ test]
1176+ fn test_from_iter_primitive ( ) {
1177+ let data = vec ! [
1178+ Some ( vec![ Some ( 0 ) , Some ( 1 ) , Some ( 2 ) ] ) ,
1179+ None ,
1180+ Some ( vec![ Some ( 3 ) , Some ( 4 ) , Some ( 5 ) ] ) ,
1181+ Some ( vec![ Some ( 6 ) , Some ( 7 ) ] ) ,
1182+ ] ;
1183+ let list_array = ListViewArray :: from_iter_primitive :: < Int32Type , _ , _ > ( data) ;
1184+
1185+ // [[0, 1, 2], NULL, [3, 4, 5], [6, 7]]
1186+ let values = Int32Array :: from ( vec ! [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ] ) ;
1187+ let offsets = ScalarBuffer :: from ( vec ! [ 0 , 3 , 3 , 6 ] ) ;
1188+ let sizes = ScalarBuffer :: from ( vec ! [ 3 , 0 , 3 , 2 ] ) ;
1189+ let field = Arc :: new ( Field :: new_list_field ( DataType :: Int32 , true ) ) ;
1190+
1191+ let mut nulls = NullBufferBuilder :: new ( 4 ) ;
1192+ nulls. append ( true ) ;
1193+ nulls. append ( false ) ;
1194+ nulls. append_n_non_nulls ( 2 ) ;
1195+ let another = ListViewArray :: new ( field, offsets, sizes, Arc :: new ( values) , nulls. finish ( ) ) ;
1196+
1197+ assert_eq ! ( list_array, another)
1198+ }
11301199}
0 commit comments