Skip to content

Commit 0b10b88

Browse files
committed
Allow closure as parameter for duplicates()
1 parent 059c9e7 commit 0b10b88

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,7 +1902,7 @@ Returns the duplicate values from the map.
19021902
public function duplicates( string $col = null ) : self
19031903
```
19041904

1905-
* @param **string|null** `$col` Key of the nested array or object to check for
1905+
* @param **\Closure|string|null** `$col` Key, path of the nested array or anonymous function with ($item, $key) parameters returning the value for comparison
19061906
* @return **self<int|string,mixed>** New map
19071907

19081908
For nested arrays, you have to pass the name of the column of the nested array which
@@ -1925,7 +1925,10 @@ Map::from( [['p' => '1'], ['p' => 1], ['p' => 2]] )->duplicates( 'p' )
19251925
// [1 => ['p' => 1]]
19261926

19271927
Map::from( [['i' => ['p' => '1']], ['i' => ['p' => 1]]] )->duplicates( 'i/p' )
1928-
// [1 => ['i' => ['p' => '1']]]
1928+
// [1 => ['i' => ['p' => 1]]]
1929+
1930+
Map::from( [['i' => ['p' => '1']], ['i' => ['p' => 1]]] )->unique( fn( $item, $key ) => $item['i']['p'] );
1931+
// [1 => ['i' => ['p' => 1]]]
19291932
```
19301933

19311934
**See also:**

src/Map.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,11 +1360,13 @@ public function dump( ?callable $callback = null ) : self
13601360
* Map::from( [1, 2, '1', 3] )->duplicates()
13611361
* Map::from( [['p' => '1'], ['p' => 1], ['p' => 2]] )->duplicates( 'p' )
13621362
* Map::from( [['i' => ['p' => '1']], ['i' => ['p' => 1]]] )->duplicates( 'i/p' )
1363+
* Map::from( [['i' => ['p' => '1']], ['i' => ['p' => 1]]] )->duplicates( fn( $item, $key ) => $item['i']['p'] )
13631364
*
13641365
* Results:
13651366
* [2 => '1']
13661367
* [1 => ['p' => 1]]
1367-
* [1 => ['i' => ['p' => '1']]]
1368+
* [1 => ['i' => ['p' => 1]]]
1369+
* [1 => ['i' => ['p' => 1]]]
13681370
*
13691371
* This does also work for multi-dimensional arrays by passing the keys
13701372
* of the arrays separated by the delimiter ("/" by default), e.g. "key1/key2/key3"
@@ -1373,13 +1375,27 @@ public function dump( ?callable $callback = null ) : self
13731375
*
13741376
* The keys are preserved using this method.
13751377
*
1376-
* @param string|null $key Key or path of the nested array or object to check for
1378+
* @param \Closure|string|null $col Key, path of the nested array or anonymous function with ($item, $key) parameters returning the value for comparison
13771379
* @return self<int|string,mixed> New map
13781380
*/
1379-
public function duplicates( ?string $key = null ) : self
1381+
public function duplicates( $col = null ) : self
13801382
{
1381-
$list = $this->list();
1382-
$items = ( $key !== null ? $this->col( $key )->toArray() : $list );
1383+
$items = $list = $this->list();
1384+
1385+
if( $col instanceof \Closure )
1386+
{
1387+
$items = [];
1388+
1389+
foreach( $this->list() as $key => $item )
1390+
{
1391+
$value = (string) $col( $item, $key );
1392+
$items[$key] = $value;
1393+
}
1394+
}
1395+
elseif( $col !== null )
1396+
{
1397+
$items = $this->col( $col )->toArray();
1398+
}
13831399

13841400
return new static( array_diff_key( $list, array_unique( $items ) ) );
13851401
}

tests/MapTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,16 @@ public function testDuplicatesPath()
733733
}
734734

735735

736+
public function testDuplicatesClosure()
737+
{
738+
$m = new Map( [['i' => ['p' => '1']], ['i' => ['p' => 1]]] );
739+
$r = $m->duplicates( fn( $item, $key ) => $item['i']['p'] );
740+
741+
$this->assertInstanceOf( Map::class, $r );
742+
$this->assertSame( [1 => ['i' => ['p' => 1]]], $r->toArray() );
743+
}
744+
745+
736746
public function testEach()
737747
{
738748
$m = new Map( $original = [1, 2, 'foo' => 'bar', 'bam' => 'baz'] );

0 commit comments

Comments
 (0)