Skip to content

Commit

Permalink
Added walk() method
Browse files Browse the repository at this point in the history
  • Loading branch information
aimeos committed Dec 17, 2019
1 parent c090617 commit 840a3cb
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 0 deletions.
52 changes: 52 additions & 0 deletions README.md
Expand Up @@ -168,6 +168,7 @@ will return:
* [unshift()](#unshift) : Adds an element at the beginning
* [usort()](#usort) : Sorts elements using callback
* [values()](#values) : Returns all elements with new keys
* [walk()](#walk) : Applies the given callback to all elements


## Method documentation
Expand Down Expand Up @@ -2248,6 +2249,57 @@ Map::from( ['x' => 'b', 2 => 'a', 'c'] )->values();
A new map with `[0 => 'b', 1 => 'a', 2 => 'c']` as content


### walk()

Applies the given callback to all elements.

To change the values of the Map, specify the value parameter as reference
(&$value). You can only change the values but not the keys nor the array
structure.

```php
public function walk( callable $callback, $data = null, bool $recursive = true ) : self
```

* @param callable $callback Function with (item, key, data) parameters
* @param mixed $data Arbitrary data that will be passed to the callback as third parameter
* @param bool $recursive TRUE to traverse sub-arrays recursively (default), FALSE to iterate Map elements only
* @return self Map for fluid interface

**Examples:**

```php
Map::from( ['a', 'B', ['c', 'd'], 'e'] )->walk( function( &$value ) {
$value = strtoupper( $value );
} );
Map::from( [66 => 'B', 97 => 'a'] )->walk( function( $value, $key ) {
echo 'ASCII ' . $key . ' is ' . $value . "\n";
} );
Map::from( [1, 2, 3] )->walk( function( &$value, $key, $data ) {
$value = $data[$value] ?? $value;
}, [1 => 'one', 2 => 'two'] );
```

**Results:**

The first example will change the Map elements to:
```php
['A', 'B', ['C', 'D'], 'E']
```
The output of the second one will be:
```
ASCII 66 is B
ASCII 97 is a
```
The last example changes the Map elements to:
```php
['one', 'two', 3]
```

By default, Map elements which are arrays will be traversed recursively.
To iterate over the Map elements only, pass FALSE as third parameter.



## Custom methods

Expand Down
47 changes: 47 additions & 0 deletions src/Map.php
Expand Up @@ -1906,6 +1906,53 @@ public function values() : self
}


/**
* Applies the given callback to all elements.
*
* To change the values of the Map, specify the value parameter as reference
* (&$value). You can only change the values but not the keys nor the array
* structure.
*
* Examples:
* Map::from( ['a', 'B', ['c', 'd'], 'e'] )->walk( function( &$value ) {
* $value = strtoupper( $value );
* } );
* Map::from( [66 => 'B', 97 => 'a'] )->walk( function( $value, $key ) {
* echo 'ASCII ' . $key . ' is ' . $value . "\n";
* } );
* Map::from( [1, 2, 3] )->walk( function( &$value, $key, $data ) {
* $value = $data[$value] ?? $value;
* }, [1 => 'one', 2 => 'two'] );
*
* Results:
* The first example will change the Map elements to:
* ['A', 'B', ['C', 'D'], 'E']
* The output of the second one will be:
* ASCII 66 is B
* ASCII 97 is a
* The last example changes the Map elements to:
* ['one', 'two', 3]
*
* By default, Map elements which are arrays will be traversed recursively.
* To iterate over the Map elements only, pass FALSE as third parameter.
*
* @param callable $callback Function with (item, key, data) parameters
* @param mixed $data Arbitrary data that will be passed to the callback as third parameter
* @param bool $recursive TRUE to traverse sub-arrays recursively (default), FALSE to iterate Map elements only
* @return self Map for fluid interface
*/
public function walk( callable $callback, $data = null, bool $recursive = true ) : self
{
if( $recursive ) {
array_walk_recursive( $this->list, $callback, $data );
} else {
array_walk( $this->list, $callback, $data );
}

return $this;
}


/**
* Returns a plain array of the given elements.
*
Expand Down
36 changes: 36 additions & 0 deletions tests/MapTest.php
Expand Up @@ -1477,6 +1477,42 @@ public function testValues()
$this->assertInstanceOf( Map::class, $r );
$this->assertEquals( [1, 'Hello'], $r->toArray() );
}


public function testWalk()
{
$m = new Map( ['a', 'B', ['c', 'd'], 'e'] );
$r = $m->walk( function( &$value ) {
$value = strtoupper( $value );
} );

$this->assertInstanceOf( Map::class, $r );
$this->assertEquals( ['A', 'B', ['C', 'D'], 'E'], $r->toArray() );
}


public function testWalkNonRecursive()
{
$m = new Map( ['a', 'B', ['c', 'd'], 'e'] );
$r = $m->walk( function( &$value ) {
$value = ( !is_array( $value ) ? strtoupper( $value ) : $value );
}, null, false );

$this->assertInstanceOf( Map::class, $r );
$this->assertEquals( ['A', 'B', ['c', 'd'], 'E'], $r->toArray() );
}


public function testWalkData()
{
$m = new Map( [1, 2, 3] );
$r = $m->walk( function( &$value, $key, $data ) {
$value = $data[$value] ?? $value;
}, [1 => 'one', 2 => 'two'] );

$this->assertInstanceOf( Map::class, $r );
$this->assertEquals( ['one', 'two', 3], $r->toArray() );
}
}


Expand Down

0 comments on commit 840a3cb

Please sign in to comment.