-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
SortIterableAggregate
and SortIterator
- Loading branch information
Showing
3 changed files
with
120 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace loophp\iterators; | ||
|
||
use Closure; | ||
use Generator; | ||
use IteratorAggregate; | ||
|
||
/** | ||
* @template TKey | ||
* @template T | ||
* | ||
* @implements IteratorAggregate<int, T> | ||
*/ | ||
final class SortIterableAggregate implements IteratorAggregate | ||
{ | ||
/** | ||
* @param iterable<TKey, T> $iterable | ||
* @param (Closure(T, T): int) $callback | ||
*/ | ||
public function __construct(private iterable $iterable, private Closure $callback) {} | ||
|
||
/** | ||
* @return Generator<int, T> | ||
*/ | ||
public function getIterator(): Generator | ||
{ | ||
yield from new SortIterator($this->iterable, $this->callback); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace loophp\iterators; | ||
|
||
use Closure; | ||
use SplHeap; | ||
|
||
/** | ||
* @template TKey | ||
* @template T | ||
* | ||
* @extends SplHeap<T> | ||
*/ | ||
final class SortIterator extends SplHeap | ||
{ | ||
/** | ||
* @param iterable<TKey, T> $iterable | ||
* @param Closure(T, T): int $callback | ||
*/ | ||
public function __construct(private iterable $iterable, private Closure $callback) | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
drupol
Author
Contributor
|
||
{ | ||
foreach ($iterable as $value) { | ||
$this->insert($value); | ||
} | ||
} | ||
|
||
/** | ||
* @param T $left | ||
* @param T $right | ||
*/ | ||
public function compare($left, $right): int | ||
This comment has been minimized.
Sorry, something went wrong.
jdreesen
Contributor
|
||
{ | ||
return ($this->callback)($left, $right); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
/** | ||
* For the full copyright and license information, please view | ||
* the LICENSE file that was distributed with this source code. | ||
*/ | ||
|
||
declare(strict_types=1); | ||
|
||
namespace tests\loophp\iterators; | ||
|
||
use loophp\iterators\SortIterableAggregate; | ||
use PHPUnit\Framework\TestCase; | ||
|
||
/** | ||
* @internal | ||
* | ||
* @coversDefaultClass \loophp\iterators | ||
*/ | ||
final class SortIterableAggregateTest extends TestCase | ||
{ | ||
public function testDoNothing(): void | ||
{ | ||
$input = ['a', 'b', 'c', 'd', 'e', 'f']; | ||
|
||
$iterator = (new SortIterableAggregate($input, static fn ($right, $left): int => $left <=> $right)); | ||
|
||
$expected = []; | ||
|
||
foreach ($iterator as $value) { | ||
$expected[] = $value; | ||
} | ||
|
||
self::assertSame($expected, $input); | ||
} | ||
|
||
public function testSimpleSort(): void | ||
{ | ||
$input = array_combine(range('c', 'a'), range('c', 'a')); | ||
|
||
$iterator = (new SortIterableAggregate($input, static fn ($right, $left): int => $left <=> $right)); | ||
|
||
$expected = []; | ||
|
||
foreach ($iterator as $value) { | ||
$expected[] = $value; | ||
} | ||
|
||
self::assertSame($expected, range('a', 'c')); | ||
} | ||
} |
The
$iterable
doesn't need theprivate
as it's only used in the constructor, right?