@@ -422,6 +422,11 @@ impl VariantArray {
422422 pub fn is_valid ( & self , index : usize ) -> bool {
423423 !self . is_null ( index)
424424 }
425+
426+ /// Returns an iterator over the values in this array
427+ pub fn iter ( & self ) -> VariantArrayIter < ' _ > {
428+ VariantArrayIter :: new ( self )
429+ }
425430}
426431
427432impl From < VariantArray > for StructArray {
@@ -436,6 +441,89 @@ impl From<VariantArray> for ArrayRef {
436441 }
437442}
438443
444+ /// An iterator over [`VariantArray`]
445+ ///
446+ /// This iterator returns `Option<Option<Variant<'a, 'a>>>` where:
447+ /// - `None` indicates the end of iteration
448+ /// - `Some(None)` indicates a null value at this position
449+ /// - `Some(Some(variant))` indicates a valid variant value
450+ ///
451+ /// # Example
452+ ///
453+ /// ```
454+ /// # use parquet_variant::Variant;
455+ /// # use parquet_variant_compute::VariantArrayBuilder;
456+ /// let mut builder = VariantArrayBuilder::new(10);
457+ /// builder.append_variant(Variant::from(42));
458+ /// builder.append_null();
459+ /// builder.append_variant(Variant::from("hello"));
460+ /// let array = builder.build();
461+ ///
462+ /// let values = array.iter().collect::<Vec<_>>();
463+ /// assert_eq!(values.len(), 3);
464+ /// assert_eq!(values[0], Some(Variant::from(42)));
465+ /// assert_eq!(values[1], None);
466+ /// assert_eq!(values[2], Some(Variant::from("hello")));
467+ /// ```
468+ #[ derive( Debug ) ]
469+ pub struct VariantArrayIter < ' a > {
470+ array : & ' a VariantArray ,
471+ head_i : usize ,
472+ tail_i : usize ,
473+ }
474+
475+ impl < ' a > VariantArrayIter < ' a > {
476+ /// Creates a new iterator over the given [`VariantArray`]
477+ pub fn new ( array : & ' a VariantArray ) -> Self {
478+ Self {
479+ array,
480+ head_i : 0 ,
481+ tail_i : array. len ( ) ,
482+ }
483+ }
484+
485+ fn value_opt ( & self , i : usize ) -> Option < Variant < ' a , ' a > > {
486+ self . array . is_valid ( i) . then ( || self . array . value ( i) )
487+ }
488+ }
489+
490+ impl < ' a > Iterator for VariantArrayIter < ' a > {
491+ type Item = Option < Variant < ' a , ' a > > ;
492+
493+ #[ inline]
494+ fn next ( & mut self ) -> Option < Self :: Item > {
495+ if self . head_i == self . tail_i {
496+ return None ;
497+ }
498+
499+ let out = self . value_opt ( self . head_i ) ;
500+
501+ self . head_i += 1 ;
502+
503+ Some ( out)
504+ }
505+
506+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
507+ let remainder = self . tail_i - self . head_i ;
508+
509+ ( remainder, Some ( remainder) )
510+ }
511+ }
512+
513+ impl < ' a > DoubleEndedIterator for VariantArrayIter < ' a > {
514+ fn next_back ( & mut self ) -> Option < Self :: Item > {
515+ if self . head_i == self . tail_i {
516+ return None ;
517+ }
518+
519+ self . tail_i -= 1 ;
520+
521+ Some ( self . value_opt ( self . tail_i ) )
522+ }
523+ }
524+
525+ impl < ' a > ExactSizeIterator for VariantArrayIter < ' a > { }
526+
439527/// One shredded field of a partially or prefectly shredded variant. For example, suppose the
440528/// shredding schema for variant `v` treats it as an object with a single field `a`, where `a` is
441529/// itself a struct with the single field `b` of type INT. Then the physical layout of the column
@@ -1062,6 +1150,8 @@ fn canonicalize_and_verify_field(field: &Arc<Field>) -> Result<Cow<'_, Arc<Field
10621150
10631151#[ cfg( test) ]
10641152mod test {
1153+ use crate :: VariantArrayBuilder ;
1154+
10651155 use super :: * ;
10661156 use arrow:: array:: { BinaryViewArray , Int32Array } ;
10671157 use arrow_schema:: { Field , Fields } ;
@@ -1244,4 +1334,89 @@ mod test {
12441334 }
12451335 ) ) ;
12461336 }
1337+
1338+ #[ test]
1339+ fn test_variant_array_iterable ( ) {
1340+ let mut b = VariantArrayBuilder :: new ( 6 ) ;
1341+
1342+ b. append_null ( ) ;
1343+ b. append_variant ( Variant :: from ( 1_i8 ) ) ;
1344+ b. append_variant ( Variant :: Null ) ;
1345+ b. append_variant ( Variant :: from ( 2_i32 ) ) ;
1346+ b. append_variant ( Variant :: from ( 3_i64 ) ) ;
1347+ b. append_null ( ) ;
1348+
1349+ let v = b. build ( ) ;
1350+
1351+ let variants = v. iter ( ) . collect :: < Vec < _ > > ( ) ;
1352+
1353+ assert_eq ! (
1354+ variants,
1355+ vec![
1356+ None ,
1357+ Some ( Variant :: Int8 ( 1 ) ) ,
1358+ Some ( Variant :: Null ) ,
1359+ Some ( Variant :: Int32 ( 2 ) ) ,
1360+ Some ( Variant :: Int64 ( 3 ) ) ,
1361+ None ,
1362+ ]
1363+ ) ;
1364+ }
1365+
1366+ #[ test]
1367+ fn test_variant_array_iter_double_ended ( ) {
1368+ let mut b = VariantArrayBuilder :: new ( 5 ) ;
1369+
1370+ b. append_variant ( Variant :: from ( 0_i32 ) ) ;
1371+ b. append_null ( ) ;
1372+ b. append_variant ( Variant :: from ( 2_i32 ) ) ;
1373+ b. append_null ( ) ;
1374+ b. append_variant ( Variant :: from ( 4_i32 ) ) ;
1375+
1376+ let array = b. build ( ) ;
1377+ let mut iter = array. iter ( ) ;
1378+
1379+ assert_eq ! ( iter. next( ) , Some ( Some ( Variant :: from( 0_i32 ) ) ) ) ;
1380+ assert_eq ! ( iter. next( ) , Some ( None ) ) ;
1381+
1382+ assert_eq ! ( iter. next_back( ) , Some ( Some ( Variant :: from( 4_i32 ) ) ) ) ;
1383+ assert_eq ! ( iter. next_back( ) , Some ( None ) ) ;
1384+ assert_eq ! ( iter. next_back( ) , Some ( Some ( Variant :: from( 2_i32 ) ) ) ) ;
1385+
1386+ assert_eq ! ( iter. next_back( ) , None ) ;
1387+ assert_eq ! ( iter. next( ) , None ) ;
1388+ }
1389+
1390+ #[ test]
1391+ fn test_variant_array_iter_reverse ( ) {
1392+ let mut b = VariantArrayBuilder :: new ( 5 ) ;
1393+
1394+ b. append_variant ( Variant :: from ( "a" ) ) ;
1395+ b. append_null ( ) ;
1396+ b. append_variant ( Variant :: from ( "aaa" ) ) ;
1397+ b. append_null ( ) ;
1398+ b. append_variant ( Variant :: from ( "aaaaa" ) ) ;
1399+
1400+ let array = b. build ( ) ;
1401+
1402+ let result: Vec < _ > = array. iter ( ) . rev ( ) . collect ( ) ;
1403+ assert_eq ! (
1404+ result,
1405+ vec![
1406+ Some ( Variant :: from( "aaaaa" ) ) ,
1407+ None ,
1408+ Some ( Variant :: from( "aaa" ) ) ,
1409+ None ,
1410+ Some ( Variant :: from( "a" ) ) ,
1411+ ]
1412+ ) ;
1413+ }
1414+
1415+ #[ test]
1416+ fn test_variant_array_iter_empty ( ) {
1417+ let v = VariantArrayBuilder :: new ( 0 ) . build ( ) ;
1418+ let mut i = v. iter ( ) ;
1419+ assert ! ( i. next( ) . is_none( ) ) ;
1420+ assert ! ( i. next_back( ) . is_none( ) ) ;
1421+ }
12471422}
0 commit comments