Skip to content

Commit

Permalink
Add ::sort() method and Operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 21, 2019
1 parent 9ea67a4 commit e50bbfd
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 0 deletions.
15 changes: 15 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,21 @@ public function it_can_slice(): void
->shouldIterateAs([5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10]);
}

public function it_can_sort(): void
{
$input = \range('A', 'E');
$input = \array_combine($input, $input);

$this
->beConstructedThrough('with', [$input]);

$this
->sort(static function ($item1, $item2) {
return $item2 <=> $item1;
})
->shouldIterateAs(['E' => 'E', 'D' => 'D', 'C' => 'C', 'B' => 'B', 'A' => 'A']);
}

public function it_can_use_range(): void
{
$this
Expand Down
12 changes: 12 additions & 0 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
use drupol\collection\Operation\Run;
use drupol\collection\Operation\Skip;
use drupol\collection\Operation\Slice;
use drupol\collection\Operation\Sort;
use drupol\collection\Operation\Walk;
use drupol\collection\Operation\Zip;
use Traversable;
Expand Down Expand Up @@ -189,6 +190,9 @@ public function keys(): CollectionInterface
return $this->run(Keys::with());
}

/**
* {@inheritdoc}
*/
public function last()
{
return $this->run(Last::with());
Expand Down Expand Up @@ -328,6 +332,14 @@ public function slice(int $offset, int $length = null): CollectionInterface
return $this->run(Slice::with($offset, $length));
}

/**
* {@inheritdoc}
*/
public function sort(callable $callback): CollectionInterface
{
return $this->run(Sort::with($callback));
}

/**
* Create a new instance by invoking the callback a given amount of times.
*
Expand Down
9 changes: 9 additions & 0 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@ public function skip(int ...$counts): self;
*/
public function slice(int $offset, int $length = null): self;

/**
* Sort the collection using a callback.
*
* @param callable $callable
*
* @return \drupol\collection\Contract\Collection
*/
public function sort(callable $callable): self;

/**
* @param callable ...$callbacks
*
Expand Down
34 changes: 34 additions & 0 deletions src/Operation/Sort.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Collection;
use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Class Sort.
*
* Be careful, this will only work with finite collection sets.
*/
final class Sort extends Operation
{
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection): CollectionInterface
{
[$callback] = $this->parameters;

return Collection::with(
static function () use ($callback, $collection) {
$array = \iterator_to_array($collection->getIterator());

\uasort($array, $callback);

yield from $array;
}
);
}
}

0 comments on commit e50bbfd

Please sign in to comment.