Skip to content

Commit

Permalink
Implement flatMap (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
nreynis committed Sep 11, 2019
1 parent 37c70fa commit 21aad81
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ All of these methods manipulate the array, but not all of them return an instanc
- `->diff(array|Chain)`
- `->filter(callable)`
- `->find(callable)`
- `->flatMap(callable)`
- `->flip()`
- `->intersect(array|Chain)`
- `->intersectAssoc(array|Chain)`
Expand Down
2 changes: 2 additions & 0 deletions src/Chain.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Cocur\Chain\Link\Filter;
use Cocur\Chain\Link\First;
use Cocur\Chain\Link\Find;
use Cocur\Chain\Link\FlatMap;
use Cocur\Chain\Link\Flip;
use Cocur\Chain\Link\Intersect;
use Cocur\Chain\Link\IntersectAssoc;
Expand Down Expand Up @@ -54,6 +55,7 @@ class Chain extends AbstractChain implements Countable
Fill,
Find,
First,
FlatMap,
Flip,
Intersect,
IntersectAssoc,
Expand Down
32 changes: 32 additions & 0 deletions src/Link/FlatMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Cocur\Chain\Link;

use Cocur\Chain\Chain;

/**
* FlatMap.
*
* @author Nicolas Reynis
*/
trait FlatMap
{
/**
* @return Chain
*/
public function flatMap(callable $callback)
{
$flattened = [];
foreach ($this->array as $index => $element) {
$transfomation = $callback($element, $index);
if (is_array($transfomation)) {
array_push($flattened, ...$transfomation);
} else {
$flattened[] = $transfomation;
}
}
$this->array = $flattened;

return $this;
}
}
1 change: 1 addition & 0 deletions tests/ChainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public function chainHasTraits()
$this->assertTrue(method_exists($c, 'filter'));
$this->assertTrue(method_exists($c, 'find'));
$this->assertTrue(method_exists($c, 'first'));
$this->assertTrue(method_exists($c, 'flatMap'));
$this->assertTrue(method_exists($c, 'flip'));
$this->assertTrue(method_exists($c, 'intersect'));
$this->assertTrue(method_exists($c, 'intersectAssoc'));
Expand Down
77 changes: 77 additions & 0 deletions tests/Link/FlatMapTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Cocur\Chain\Link;

use PHPUnit_Framework_TestCase;

/**
* MapTest.
*
* @author Nicolas Reynis
* @group unit
*/
class FlatMapTest extends PHPUnit_Framework_TestCase
{
/**
* @test
* @covers Cocur\Chain\Link\FlatMap::flatMap()
*/
public function flatMapAppliesMapToArray()
{
/** @var \Cocur\Chain\Link\FlatMap $mock */
$mock = $this->getMockForTrait('Cocur\Chain\Link\FlatMap');
$mock->array = ['foobar', 'bar'];
$mock->flatMap(function ($v) { return [str_replace('bar', 'foo', $v)]; });

$this->assertEquals('foofoo', $mock->array[0]);
$this->assertEquals('foo', $mock->array[1]);
}

/**
* @test
* @covers Cocur\Chain\Link\FlatMap::flatMap()
*/
public function flatMapCallbackReceivesAlsoArrayKeys()
{
/** @var \Cocur\Chain\Link\FlatMap $mock */
$mock = $this->getMockForTrait('Cocur\Chain\Link\FlatMap');
$mock->array = ['foo' => 'fizz', 'bar' => 'buzz'];
$mock->flatMap(function ($v, $k) {
return $k == 'foo' ? [str_replace('fizz', 'bang', $v)] : [$v];
});

$this->assertEquals(['bang', 'buzz'], $mock->array);
}

/**
* @test
* @covers Cocur\Chain\Link\FlatMap::flatMap()
*/
public function flatMapCallbackCanReturnScalarOrArray()
{
/** @var \Cocur\Chain\Link\FlatMap $mock */
$mock = $this->getMockForTrait('Cocur\Chain\Link\FlatMap');
$mock->array = ['fizz', 'buzz'];
$mock->flatMap(function ($v, $k) {
return $k == 1 ? [$v] : $v;
});

$this->assertEquals(['fizz', 'buzz'], $mock->array);
}

/**
* @test
* @covers Cocur\Chain\Link\FlatMap::flatMap()
*/
public function flatMapAcceptsEmptyArray()
{
/** @var \Cocur\Chain\Link\FlatMap $mock */
$mock = $this->getMockForTrait('Cocur\Chain\Link\FlatMap');
$mock->array = [];
$mock->flatMap(function ($v) {
return $v;
});

$this->assertEquals([], $mock->array);
}
}

0 comments on commit 21aad81

Please sign in to comment.