diff --git a/README.md b/README.md
index 1803287..3471a46 100644
--- a/README.md
+++ b/README.md
@@ -263,6 +263,7 @@ will return:
toArray
toJson
toUrl
+transform
transpose
traverse
tree
@@ -456,6 +457,7 @@ will return:
* [suffix()](#suffix) : Adds a suffix to each map entry
* [toJson()](#tojson) : Returns the elements in JSON format
* [toUrl()](#tourl) : Creates a HTTP query string
+* [transfrom()](#transfrom) : Applies a callback to each element which creates new key/value pairs
* [transpose()](#transpose) : Exchanges rows and columns for a two dimensional map
* [traverse()](#traverse) : Traverses trees of nested items passing each item to the callback
* [trim()](#trim) : Removes the passed characters from the left/right of all strings
@@ -3354,7 +3356,7 @@ Map::from( ["a b c", "cbxa"] )->ltrim( 'abc' );
### map()
-Calls the passed function once for each element and returns a new map for the result.
+Maps new values to the existing keys using the passed function and returns a new map for the result.
```php
public function map( callable $callback ) : self
@@ -5388,6 +5390,44 @@ Map::from( ['a' => ['b' => 'abc', 'c' => 'def'], 'd' => 123] )->toUrl();
```
+### transform()
+
+Creates new key/value pairs using the passed function and returns a new map for the result.
+
+```php
+public function transform( \Closure $callback ) : self
+```
+
+* @param **\Closure** `$callback` Function with (value, key) parameters and returns an array of new key/value pair(s)
+* @return **self<int|string,mixed>** New map with the new key/value pairs
+
+If a key is returned twice, the last value will overwrite previous values.
+
+**Examples:**
+
+```php
+Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return [$key . '-2' => $value * 2];
+} );
+// ['a-2' => 4, 'b-2' => 8]
+
+Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return [$key => $value * 2, $key . $key => $value * 4];
+} );
+// ['a' => 4, 'aa' => 8, 'b' => 8, 'bb' => 16]
+
+Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return $key < 'b' ? [$key => $value * 2] : null;
+} );
+// ['a' => 4]
+
+Map::from( ['la' => 2, 'le' => 4, 'li' => 6] )->transform( function( $value, $key ) {
+ return [$key[0] => $value * 2];
+} );
+// ['l' => 12]
+```
+
+
### transpose()
Exchanges rows and columns for a two dimensional map.
diff --git a/src/Map.php b/src/Map.php
index 9d031e6..f328d6d 100644
--- a/src/Map.php
+++ b/src/Map.php
@@ -2850,7 +2850,7 @@ public function ltrim( string $chars = " \n\r\t\v\x00" ) : self
/**
- * Calls the passed function once for each element and returns a new map for the result.
+ * Maps new values to the existing keys using the passed function and returns a new map for the result.
*
* Examples:
* Map::from( ['a' => 2, 'b' => 4] )->map( function( $value, $key ) {
@@ -4909,6 +4909,49 @@ public function toUrl() : string
}
+ /**
+ * Creates new key/value pairs using the passed function and returns a new map for the result.
+ *
+ * Examples:
+ * Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ * return [$key . '-2' => $value * 2];
+ * } );
+ * Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ * return [$key => $value * 2, $key . $key => $value * 4];
+ * } );
+ * Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ * return $key < 'b' ? [$key => $value * 2] : null;
+ * } );
+ * Map::from( ['la' => 2, 'le' => 4, 'li' => 6] )->transform( function( $value, $key ) {
+ * return [$key[0] => $value * 2];
+ * } );
+ *
+ * Results:
+ * ['a-2' => 4, 'b-2' => 8]
+ * ['a' => 4, 'aa' => 8, 'b' => 8, 'bb' => 16]
+ * ['a' => 4]
+ * ['l' => 12]
+ *
+ * If a key is returned twice, the last value will overwrite previous values.
+ *
+ * @param \Closure $callback Function with (value, key) parameters and returns an array of new key/value pair(s)
+ * @return self New map with the new key/value pairs
+ */
+ public function transform( \Closure $callback ) : self
+ {
+ $result = [];
+
+ foreach( $this->list() as $key => $value )
+ {
+ foreach( (array) $callback( $value, $key ) as $newkey => $newval ) {
+ $result[$newkey] = $newval;
+ }
+ }
+
+ return new static( $result );
+ }
+
+
/**
* Exchanges rows and columns for a two dimensional map.
*
diff --git a/tests/MapTest.php b/tests/MapTest.php
index a19fc66..74dc80f 100644
--- a/tests/MapTest.php
+++ b/tests/MapTest.php
@@ -3204,6 +3204,50 @@ public function testTimesObjects()
}
+ public function testTransform()
+ {
+ $m = Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return [$key . '-2' => $value * 2];
+ } );
+
+ $this->assertInstanceOf( Map::class, $m );
+ $this->assertSame( ['a-2' => 4, 'b-2' => 8], $m->toArray() );
+ }
+
+
+ public function testTransformExtend()
+ {
+ $m = Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return [$key => $value * 2, $key . $key => $value * 4];
+ } );
+
+ $this->assertInstanceOf( Map::class, $m );
+ $this->assertSame( ['a' => 4, 'aa' => 8, 'b' => 8, 'bb' => 16], $m->toArray() );
+ }
+
+
+ public function testTransformShorten()
+ {
+ $m = Map::from( ['a' => 2, 'b' => 4] )->transform( function( $value, $key ) {
+ return $key < 'b' ? [$key => $value * 2] : null;
+ } );
+
+ $this->assertInstanceOf( Map::class, $m );
+ $this->assertSame( ['a' => 4], $m->toArray() );
+ }
+
+
+ public function testTransformOverwrite()
+ {
+ $m = Map::from( ['la' => 2, 'le' => 4, 'li' => 6] )->transform( function( $value, $key ) {
+ return [$key[0] => $value * 2];
+ } );
+
+ $this->assertInstanceOf( Map::class, $m );
+ $this->assertSame( ['l' => 12], $m->toArray() );
+ }
+
+
public function testTranspose()
{
$m = Map::from( [