@@ -32,8 +32,22 @@ class Arr
32
32
const MAP_ARRAY_VALUE_KEYS_LIST = 2 ;
33
33
const MAP_ARRAY_KEYS_ARRAY_VALUE = 4 ;
34
34
35
+ const UNPACK_ALL = 1 ;
36
+ /**
37
+ * Preserve arrays with highest nesting level (if they are not assoc) as element values instead of unpacking them
38
+ */
39
+ const UNPACK_PRESERVE_LIST_ARRAY = 2 ;
40
+ /**
41
+ * Preserve arrays with highest nesting level (if they are assoc) as element values instead of unpacking them
42
+ */
43
+ const UNPACK_PRESERVE_ASSOC_ARRAY = 4 ;
44
+ /**
45
+ * Preserve all arrays with highest nesting level as element values instead of unpacking them
46
+ */
47
+ const UNPACK_PRESERVE_ARRAY = 8 ;
35
48
36
49
private const AUTO_INDEX_KEY = '[] ' ;
50
+ private const KEY_SEPARATOR = '. ' ;
37
51
38
52
/*--------------------------------------------------------------------------------------*\
39
53
| Common |
@@ -58,7 +72,7 @@ class Arr
58
72
public static function getKeysArray ($ keys ): array
59
73
{
60
74
if (is_string ($ keys )) {
61
- return empty ($ keys ) ? [] : explode (' . ' , $ keys );
75
+ return empty ($ keys ) ? [] : explode (self :: KEY_SEPARATOR , $ keys );
62
76
}
63
77
return is_null ($ keys ) ? [] : array_filter (array_values (self ::forceArray ($ keys )), function ($ value ) {
64
78
return $ value !== null && $ value !== '' && (is_string ($ value ) || is_int ($ value ));
@@ -153,21 +167,34 @@ public static function setNestedElement(array $array, $keys, $value): array
153
167
* Converts multidimensional array to map of keys concatenated by dot and corresponding values
154
168
*
155
169
* @param array $array
156
- * @param array $keys Internal keys storage used for recursive calls
170
+ * @param int $mode Modify behaviour of unpack (see description of Arr::UNPACK_ constants)
157
171
* @return array
158
172
*/
159
- public static function unpack (array $ array , array $ keys = []): array
173
+ public static function unpack (array $ array , int $ mode = self ::UNPACK_ALL ): array
174
+ {
175
+ return self ::_unpack ($ array , $ mode );
176
+ }
177
+
178
+ private static function _unpack (array $ array , int $ mode = self ::UNPACK_ALL , array $ keys = []): array
160
179
{
161
180
$ result = [];
162
181
163
182
foreach ($ array as $ key => $ value ) {
164
183
165
- if (is_array ($ value )) {
184
+ if (is_array ($ value ) && !(
185
+ // Check if value IS NOT a subject for preserve mode
186
+ !self ::isNested ($ value ) && // Preserve mode only work for highest depth elements
187
+ (
188
+ ($ mode === self ::UNPACK_PRESERVE_LIST_ARRAY && !self ::isAssoc ($ value , true )) ||
189
+ ($ mode === self ::UNPACK_PRESERVE_ASSOC_ARRAY && self ::isAssoc ($ value , true )) ||
190
+ $ mode === self ::UNPACK_PRESERVE_ARRAY
191
+ )
192
+ )) {
166
193
$ keys [] = $ key ;
167
- $ result += self ::unpack ($ value , $ keys );
194
+ $ result += self ::_unpack ($ value, $ mode , $ keys );
168
195
array_pop ($ keys );
169
196
} else {
170
- $ result [implode (' . ' , array_merge ($ keys , [$ key ]))] = $ value ;
197
+ $ result [implode (self :: KEY_SEPARATOR , array_merge ($ keys , [$ key ]))] = $ value ;
171
198
}
172
199
}
173
200
@@ -251,7 +278,9 @@ public static function isEmpty($array): bool
251
278
*
252
279
* @param array $array
253
280
* @param bool $strict
254
- * If false then this function will match any array that doesn't contain integer keys
281
+ * <p>If <i>false</i> then this function will match any array that doesn't contain integer keys.</p>
282
+ * <p>If <i>true</i> then this function match only arrays with sequence of integers starting from zero (range from 0 to elements_number - 1) as keys.</p>
283
+ *
255
284
* @return boolean
256
285
*/
257
286
public static function isAssoc (array $ array , bool $ strict = false ): bool
@@ -772,7 +801,7 @@ public static function createMulti(array $keys, ?array $values = null): array
772
801
* Make variable an array (according to flag settings)
773
802
*
774
803
* @param mixed $var
775
- * @param int $flag Set flag(s) to preserve specific values from being converted to array
804
+ * @param int $flag Set flag(s) to preserve specific values from being converted to array (see Arr::FORCE_ARRAY_ constants)
776
805
* @return array
777
806
*/
778
807
public static function forceArray ($ var , int $ flag = self ::FORCE_ARRAY_ALL )
0 commit comments