11using System . Text . Json ;
22using System . Text . Json . Nodes ;
3+ using Hyperbee . Json . Extensions ;
34using Hyperbee . Json . Path ;
45using Hyperbee . Json . Pointer ;
56using Hyperbee . Json . Query ;
@@ -28,18 +29,72 @@ public bool TryGetFromPointer( in JsonNode node, JsonSegment segment, out JsonNo
2829 public bool DeepEquals ( JsonNode left , JsonNode right ) =>
2930 JsonNode . DeepEquals ( left , right ) ;
3031
31- public IEnumerable < ( JsonNode Value , string Key ) > GetChildren ( in JsonNode value , bool complexTypesOnly = false )
32+ public IEnumerable < JsonNode > GetChildren ( JsonNode value , ChildEnumerationOptions options )
3233 {
34+ bool complexTypesOnly = options . HasFlag ( ChildEnumerationOptions . ComplexTypesOnly ) ;
35+ bool reverse = options . HasFlag ( ChildEnumerationOptions . Reverse ) ;
36+
3337 // allocating is faster than using yield return and less memory intensive.
34- // using stack results in fewer overall allocations than calling reverse,
35- // which internally allocates, and then discards, a new array.
38+ // using a collection results in fewer overall allocations than calling
39+ // LINQ reverse, which internally allocates, and then discards, a new array.
40+
41+ List < JsonNode > results ;
42+
43+ switch ( value )
44+ {
45+ case JsonArray jsonArray :
46+ {
47+ var length = jsonArray . Count ;
48+ results = new List < JsonNode > ( length ) ;
49+
50+ for ( var index = 0 ; index < length ; index ++ )
51+ {
52+ var child = value [ index ] ;
53+
54+ if ( complexTypesOnly && child is not ( JsonArray or JsonObject ) )
55+ continue ;
56+
57+ results . Add ( child ) ;
58+ }
59+
60+ return reverse ? results . EnumerateReverse ( ) : results ;
61+ }
62+ case JsonObject jsonObject :
63+ {
64+ results = new List < JsonNode > ( 8 ) ;
65+
66+ foreach ( var child in jsonObject )
67+ {
68+ if ( complexTypesOnly && child . Value is not ( JsonArray or JsonObject ) )
69+ continue ;
70+
71+ results . Add ( child . Value ) ;
72+ }
73+
74+ return reverse ? results . EnumerateReverse ( ) : results ;
75+ }
76+ }
77+
78+ return [ ] ;
79+ }
80+
81+ public IEnumerable < ( JsonNode Value , string Key ) > GetChildrenWithName ( in JsonNode value , ChildEnumerationOptions options )
82+ {
83+ bool complexTypesOnly = options . HasFlag ( ChildEnumerationOptions . ComplexTypesOnly ) ;
84+ bool reverse = options . HasFlag ( ChildEnumerationOptions . Reverse ) ;
85+
86+ // allocating is faster than using yield return and less memory intensive.
87+ // using a collection results in fewer overall allocations than calling
88+ // LINQ reverse, which internally allocates, and then discards, a new array.
89+
90+ List < ( JsonNode , string ) > results ;
3691
3792 switch ( value )
3893 {
3994 case JsonArray jsonArray :
4095 {
4196 var length = jsonArray . Count ;
42- var results = new Stack < ( JsonNode , string ) > ( length ) ; // stack will reverse items
97+ results = new List < ( JsonNode , string ) > ( length ) ;
4398
4499 for ( var index = 0 ; index < length ; index ++ )
45100 {
@@ -48,24 +103,24 @@ public bool DeepEquals( JsonNode left, JsonNode right ) =>
48103 if ( complexTypesOnly && child is not ( JsonArray or JsonObject ) )
49104 continue ;
50105
51- results . Push ( ( child , IndexHelper . GetIndexString ( index ) ) ) ;
106+ results . Add ( ( child , IndexHelper . GetIndexString ( index ) ) ) ;
52107 }
53108
54- return results ;
109+ return reverse ? results . EnumerateReverse ( ) : results ;
55110 }
56111 case JsonObject jsonObject :
57112 {
58- var results = new Stack < ( JsonNode , string ) > ( ) ; // stack will reverse items
113+ results = new List < ( JsonNode , string ) > ( 8 ) ;
59114
60115 foreach ( var child in jsonObject )
61116 {
62117 if ( complexTypesOnly && child . Value is not ( JsonArray or JsonObject ) )
63118 continue ;
64119
65- results . Push ( ( child . Value , child . Key ) ) ;
120+ results . Add ( ( child . Value , child . Key ) ) ;
66121 }
67122
68- return results ;
123+ return reverse ? results . EnumerateReverse ( ) : results ;
69124 }
70125 }
71126
0 commit comments