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