@@ -1767,7 +1767,7 @@ public function firstKey( $default = null )
17671767
17681768
17691769 /**
1770- * Creates a new map with all sub-array elements added recursively withput overwriting existing keys.
1770+ * Creates a new map with all sub-array elements added recursively without overwriting existing keys.
17711771 *
17721772 * Examples:
17731773 * Map::from( [[0, 1], [2, 3]] )->flat();
@@ -1800,7 +1800,38 @@ public function flat( ?int $depth = null ) : self
18001800 }
18011801
18021802 $ result = [];
1803- $ this ->flatten ( $ this ->list (), $ result , $ depth ?? 0x7fffffff );
1803+ $ this ->nflatten ( $ this ->list (), $ result , $ depth ?? 0x7fffffff );
1804+ return new static ( $ result );
1805+ }
1806+
1807+
1808+ /**
1809+ * Creates a new map with keys joined recursively.
1810+ *
1811+ * Examples:
1812+ * Map::from( ['a' => ['b' => ['c' => 1, 'd' => 2]], 'b' => ['e' => 3]] )->flatten();
1813+ * Map::from( ['a' => ['b' => ['c' => 1, 'd' => 2]], 'b' => ['e' => 3]] )->flatten( 1 );
1814+ * Map::from( ['a' => ['b' => ['c' => 1, 'd' => 2]], 'b' => ['e' => 3]] )->sep( '.' )->flatten();
1815+ *
1816+ * Results:
1817+ * ['a/b/c' => 1, 'a/b/d' => 2, 'b/e' => 3]
1818+ * ['a/b' => ['c' => 1, 'd' => 2], 'b/e' => 3]
1819+ * ['a.b.c' => 1, 'a.b.d' => 2, 'b.e' => 3]
1820+ *
1821+ * To create the original multi-dimensional array again, use the unflatten() method.
1822+ *
1823+ * @param int|null $depth Number of levels to flatten multi-dimensional arrays or NULL for all
1824+ * @return self<string,mixed> New map with keys joined recursively, up to the specified depth
1825+ * @throws \InvalidArgumentException If depth must be greater or equal than 0 or NULL
1826+ */
1827+ public function flatten ( ?int $ depth = null ) : self
1828+ {
1829+ if ( $ depth < 0 ) {
1830+ throw new \InvalidArgumentException ( 'Depth must be greater or equal than 0 or NULL ' );
1831+ }
1832+
1833+ $ result = [];
1834+ $ this ->rflatten ( $ this ->list (), $ result , $ depth ?? 0x7fffffff );
18041835 return new static ( $ result );
18051836 }
18061837
@@ -5810,6 +5841,8 @@ public function uksorted( callable $callback ) : self
58105841 * Results:
58115842 * ['a' => ['b' => ['c' => 1, 'd' => 2]], 'b' => ['e' => 3]]
58125843 *
5844+ * This is the inverse method for flatten().
5845+ *
58135846 * @return self<int|string,mixed> New map with multi-dimensional arrays
58145847 */
58155848 public function unflatten () : self
@@ -6225,26 +6258,6 @@ protected function array( $elements ) : array
62256258 }
62266259
62276260
6228- /**
6229- * Flattens a multi-dimensional array or map into a single level array.
6230- *
6231- * @param iterable<int|string,mixed> $entries Single of multi-level array, map or everything foreach can be used with
6232- * @param array<mixed> &$result Will contain all elements from the multi-dimensional arrays afterwards
6233- * @param int $depth Number of levels to flatten in multi-dimensional arrays
6234- */
6235- protected function flatten ( iterable $ entries , array &$ result , int $ depth ) : void
6236- {
6237- foreach ( $ entries as $ entry )
6238- {
6239- if ( is_iterable ( $ entry ) && $ depth > 0 ) {
6240- $ this ->flatten ( $ entry , $ result , $ depth - 1 );
6241- } else {
6242- $ result [] = $ entry ;
6243- }
6244- }
6245- }
6246-
6247-
62486261 /**
62496262 * Flattens a multi-dimensional array or map into a single level array.
62506263 *
@@ -6300,6 +6313,47 @@ protected function mapper( $key = null ) : \Closure
63006313 }
63016314
63026315
6316+ /**
6317+ * Flattens a multi-dimensional array or map into a single level array.
6318+ *
6319+ * @param iterable<int|string,mixed> $entries Single of multi-level array, map or everything foreach can be used with
6320+ * @param array<mixed> &$result Will contain all elements from the multi-dimensional arrays afterwards
6321+ * @param int $depth Number of levels to flatten in multi-dimensional arrays
6322+ */
6323+ protected function nflatten ( iterable $ entries , array &$ result , int $ depth ) : void
6324+ {
6325+ foreach ( $ entries as $ entry )
6326+ {
6327+ if ( is_iterable ( $ entry ) && $ depth > 0 ) {
6328+ $ this ->nflatten ( $ entry , $ result , $ depth - 1 );
6329+ } else {
6330+ $ result [] = $ entry ;
6331+ }
6332+ }
6333+ }
6334+
6335+
6336+ /**
6337+ * Flattens a multi-dimensional array or map into an array with joined keys.
6338+ *
6339+ * @param iterable<int|string,mixed> $entries Single of multi-level array, map or everything foreach can be used with
6340+ * @param array<int|string,mixed> $result Will contain joined key/value pairs from the multi-dimensional arrays afterwards
6341+ * @param int $depth Number of levels to flatten in multi-dimensional arrays
6342+ * @param string $path Path prefix of the current key
6343+ */
6344+ protected function rflatten ( iterable $ entries , array &$ result , int $ depth , string $ path = '' ) : void
6345+ {
6346+ foreach ( $ entries as $ key => $ entry )
6347+ {
6348+ if ( is_iterable ( $ entry ) && $ depth > 0 ) {
6349+ $ this ->rflatten ( $ entry , $ result , $ depth - 1 , $ path . $ key . $ this ->sep );
6350+ } else {
6351+ $ result [$ path . $ key ] = $ entry ;
6352+ }
6353+ }
6354+ }
6355+
6356+
63036357 /**
63046358 * Returns the position of the first element that doesn't match the condition
63056359 *
0 commit comments