@@ -59,97 +59,16 @@ public function __construct(iterable $subset, bool $strict = false)
59
59
*/
60
60
public function evaluate ($ other , $ description = '' , $ returnResult = false )
61
61
{
62
- // Anonymous function that checks whether the given array is
63
- // associative.
64
- $ is_associative = function (array $ array ): bool {
65
- return \array_reduce (\array_keys ($ array ), function (bool $ carry , $ key ): bool {
66
- return $ carry || \is_string ($ key );
67
- }, false );
68
- };
69
-
70
- // Anonymous function that compares the two given values using either
71
- // strict or loose comparisons.
72
- $ strict = $ this ->strict ;
73
- $ compare = function ($ first , $ second ) use ($ strict ): bool {
74
- return $ strict ? $ first === $ second : $ first == $ second ;
75
- };
76
-
77
- // Anonymous function that sorts the given multidimensional array.
78
- $ deep_sort = function (array &$ array ) use (&$ deep_sort , $ is_associative ): void {
79
- foreach ($ array as &$ value ) {
80
- if (\is_array ($ value )) {
81
- $ deep_sort ($ value );
82
- }
83
- }
84
-
85
- if ($ is_associative ($ array )) {
86
- \ksort ($ array );
87
- } else {
88
- \sort ($ array );
89
- }
90
- };
91
-
92
- $ array_intersect_recursive = function (array $ array , array $ subset ) use (&$ array_intersect_recursive , $ is_associative , $ compare ): array {
93
- $ intersect = [];
94
-
95
- if ($ is_associative ($ subset )) {
96
- // If the subset is an associative array, get the intersection
97
- // while preserving the keys.
98
- foreach ($ subset as $ key => $ subset_value ) {
99
- if (\array_key_exists ($ key , $ array )) {
100
- $ array_value = $ array [$ key ];
101
-
102
- if (\is_array ($ subset_value ) && \is_array ($ array_value )) {
103
- $ intersect [$ key ] = $ array_intersect_recursive ($ array_value , $ subset_value );
104
- } elseif ($ compare ($ subset_value , $ array_value )) {
105
- $ intersect [$ key ] = $ array_value ;
106
- }
107
- }
108
- }
109
- } else {
110
- // If the subset is an indexed array, loop over all entries in
111
- // the haystack and check if they match the ones in the subset.
112
- foreach ($ array as $ array_value ) {
113
- if (\is_array ($ array_value )) {
114
- foreach ($ subset as $ key => $ subset_value ) {
115
- if (\is_array ($ subset_value )) {
116
- $ recursed = $ array_intersect_recursive ($ array_value , $ subset_value );
117
-
118
- if (!empty ($ recursed )) {
119
- $ intersect [$ key ] = $ recursed ;
120
-
121
- break ;
122
- }
123
- }
124
- }
125
- } else {
126
- foreach ($ subset as $ key => $ subset_value ) {
127
- if (!\is_array ($ subset_value ) && $ compare (
128
- $ subset_value ,
129
- $ array_value
130
- )) {
131
- $ intersect [$ key ] = $ array_value ;
132
-
133
- break ;
134
- }
135
- }
136
- }
137
- }
138
- }
139
-
140
- return $ intersect ;
141
- };
142
-
143
62
//type cast $other & $this->subset as an array to allow
144
63
//support in standard array functions.
145
64
$ other = $ this ->toArray ($ other );
146
65
$ this ->subset = $ this ->toArray ($ this ->subset );
147
66
148
- $ intersect = $ array_intersect_recursive ($ other , $ this ->subset );
149
- $ deep_sort ($ intersect );
150
- $ deep_sort ($ this ->subset );
67
+ $ intersect = $ this -> arrayIntersectRecursive ($ other , $ this ->subset );
68
+ $ this -> deepSort ($ intersect );
69
+ $ this -> deepSort ($ this ->subset );
151
70
152
- $ result = $ compare ($ intersect , $ this ->subset );
71
+ $ result = $ this -> compare ($ intersect , $ this ->subset );
153
72
154
73
if ($ returnResult ) {
155
74
return $ result ;
@@ -209,4 +128,83 @@ private function toArray(iterable $other): array
209
128
// Keep BC even if we know that array would not be the expected one
210
129
return (array ) $ other ;
211
130
}
131
+
132
+ private function isAssociative (array $ array ): bool
133
+ {
134
+ return \array_reduce (\array_keys ($ array ), function (bool $ carry , $ key ): bool {
135
+ return $ carry || \is_string ($ key );
136
+ }, false );
137
+ }
138
+
139
+ private function compare ($ first , $ second ): bool
140
+ {
141
+ return $ this ->strict ? $ first === $ second : $ first == $ second ;
142
+ }
143
+
144
+ private function deepSort (array &$ array ): void
145
+ {
146
+ foreach ($ array as &$ value ) {
147
+ if (\is_array ($ value )) {
148
+ $ this ->deepSort ($ value );
149
+ }
150
+ }
151
+
152
+ if ($ this ->isAssociative ($ array )) {
153
+ \ksort ($ array );
154
+ } else {
155
+ \sort ($ array );
156
+ }
157
+ }
158
+
159
+ private function arrayIntersectRecursive (array $ array , array $ subset ): array
160
+ {
161
+ $ intersect = [];
162
+
163
+ if ($ this ->isAssociative ($ subset )) {
164
+ // If the subset is an associative array, get the intersection while
165
+ // preserving the keys.
166
+ foreach ($ subset as $ key => $ subset_value ) {
167
+ if (\array_key_exists ($ key , $ array )) {
168
+ $ array_value = $ array [$ key ];
169
+
170
+ if (\is_array ($ subset_value ) && \is_array ($ array_value )) {
171
+ $ intersect [$ key ] = $ this ->arrayIntersectRecursive ($ array_value , $ subset_value );
172
+ } elseif ($ this ->compare ($ subset_value , $ array_value )) {
173
+ $ intersect [$ key ] = $ array_value ;
174
+ }
175
+ }
176
+ }
177
+ } else {
178
+ // If the subset is an indexed array, loop over all entries in the
179
+ // haystack and check if they match the ones in the subset.
180
+ foreach ($ array as $ array_value ) {
181
+ if (\is_array ($ array_value )) {
182
+ foreach ($ subset as $ key => $ subset_value ) {
183
+ if (\is_array ($ subset_value )) {
184
+ $ recursed = $ this ->arrayIntersectRecursive ($ array_value , $ subset_value );
185
+
186
+ if (!empty ($ recursed )) {
187
+ $ intersect [$ key ] = $ recursed ;
188
+
189
+ break ;
190
+ }
191
+ }
192
+ }
193
+ } else {
194
+ foreach ($ subset as $ key => $ subset_value ) {
195
+ if (!\is_array ($ subset_value ) && $ this ->compare (
196
+ $ subset_value ,
197
+ $ array_value
198
+ )) {
199
+ $ intersect [$ key ] = $ array_value ;
200
+
201
+ break ;
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ return $ intersect ;
209
+ }
212
210
}
0 commit comments