Skip to content

Commit

Permalink
Fix LazyCollection#unique() double enumeration
Browse files Browse the repository at this point in the history
Fixes #38817
  • Loading branch information
JosephSilber committed Sep 30, 2021
1 parent b5a70e2 commit f0ac775
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 22 deletions.
22 changes: 22 additions & 0 deletions src/Illuminate/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,28 @@ public function transform(callable $callback)
return $this;
}

/**
* Return only unique items from the collection array.
*
* @param string|callable|null $key
* @param bool $strict
* @return static
*/
public function unique($key = null, $strict = false)
{
$callback = $this->valueRetriever($key);

$exists = [];

return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
if (in_array($id = $callback($item, $key), $exists, $strict)) {
return true;
}

$exists[] = $id;
});
}

/**
* Reset the keys on the underlying array.
*
Expand Down
24 changes: 24 additions & 0 deletions src/Illuminate/Collections/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,30 @@ public function tapEach(callable $callback)
});
}

/**
* Return only unique items from the collection array.
*
* @param string|callable|null $key
* @param bool $strict
* @return static
*/
public function unique($key = null, $strict = false)
{
$callback = $this->valueRetriever($key);

return new static(function () use ($callback, $strict) {
$exists = [];

foreach ($this as $key => $item) {
if (! in_array($id = $callback($item, $key), $exists, $strict)) {
yield $key => $item;

$exists[] = $id;
}
}
});
}

/**
* Reset the keys on the underlying array.
*
Expand Down
22 changes: 0 additions & 22 deletions src/Illuminate/Collections/Traits/EnumeratesValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -773,28 +773,6 @@ public function reject($callback = true)
});
}

/**
* Return only unique items from the collection array.
*
* @param string|callable|null $key
* @param bool $strict
* @return static
*/
public function unique($key = null, $strict = false)
{
$callback = $this->valueRetriever($key);

$exists = [];

return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) {
if (in_array($id = $callback($item, $key), $exists, $strict)) {
return true;
}

$exists[] = $id;
});
}

/**
* Return only unique items from the collection array using strict comparison.
*
Expand Down
9 changes: 9 additions & 0 deletions tests/Support/SupportLazyCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,13 @@ public function testTapEach()
$this->assertSame([1, 2, 3, 4, 5], $data);
$this->assertSame([1, 2, 3, 4, 5], $tapped);
}

public function testUniqueDoubleEnumeration()
{
$data = LazyCollection::times(2)->unique();

$data->all();

$this->assertSame([1, 2], $data->all());
}
}

0 comments on commit f0ac775

Please sign in to comment.