Skip to content

Commit

Permalink
Update Last operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 22, 2020
1 parent 126bf8a commit a8cb98f
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 112 deletions.
42 changes: 36 additions & 6 deletions docs/pages/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,41 @@ Signature: ``Collection::keys();``
$collection = Collection::with(range('a', 'z'))
->keys();
last
~~~~

Get the last items from the collection passing the given truth test.

Interface: `Lastable`_

Signature: ``Collection::last(?callable $callback = null, int $size = 1);``

.. code-block:: php
$generator = static function (): Generator {
yield 'a' => 'a';
yield 'b' => 'b';
yield 'c' => 'c';
yield 'a' => 'd';
yield 'b' => 'e';
yield 'c' => 'f';
};
Collection::fromIterable($generator())
->last(
static function ($value, $key) {
return 'b' === $key;
}
); // ['b' => 'e']
Collection::fromIterable($generator())
->last(
static function ($value, $key) {
return 'b' === $key;
},
2
); // ['b' => 'e', 'b' => 'b']
limit
~~~~~

Expand Down Expand Up @@ -1346,11 +1381,6 @@ implode

Interface: `Implodeable`_

last
~~~~

Interface: `Lastable`_

nullsy
~~~~~~

Expand Down Expand Up @@ -1412,7 +1442,7 @@ Interface: `Truthyable`_
.. _Intersectkeysable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Intersectkeysable.php
.. _Intersperseable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Intersperseable.php
.. _Keysable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Keysable.php
.. _Lastable: https://github.com/loophp/collection/blob/master/src/Contract/Tranformation/Lastable.php
.. _Lastable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Lastable.php
.. _Limitable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Limitable.php
.. _Loopable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Loopable.php
.. _Mapable: https://github.com/loophp/collection/blob/master/src/Contract/Operation/Mapable.php
Expand Down
44 changes: 38 additions & 6 deletions spec/loophp/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -869,21 +869,53 @@ public function it_can_get_the_last_item(): void
{
$this::fromIterable(range('A', 'F'))
->last()
->shouldReturn('F');
->shouldIterateAs([5 => 'F']);

$this::fromIterable(['A'])
->last()
->shouldReturn('A');
->shouldIterateAs([0 => 'A']);

$this::fromIterable([])
->last()
->shouldReturn(null);
->shouldIterateAs([]);

$this::fromIterable(range('A', 'F'))
->last(static function ($value, $key) {
return false;
}, 'foo')
->shouldReturn('foo');
})
->shouldIterateAs([]);

$generator = static function (): Generator {
yield 'a' => 'a';

yield 'b' => 'b';

yield 'c' => 'c';

yield 'a' => 'd';

yield 'b' => 'e';

yield 'c' => 'f';
};

$this::fromIterable($generator())
->last(static function ($value, $key) {
return 'b' === $key;
})
->shouldIterateAs(['b' => 'e']);

$output = static function (): Generator {
yield 'b' => 'e';

yield 'b' => 'b';
};

$this::fromIterable($generator())
->last(static function ($value, $key) {
return 'b' === $key;
}, 2)
->shouldIterateAs($output());
}

public function it_can_group()
Expand Down Expand Up @@ -1977,7 +2009,7 @@ public function it_can_use_with(): void
->split(static function ($v) {
return "\n" === $v;
})
->tail(1)
->last()
->unwrap()
->implode()
->shouldReturn('indent_size = 4');
Expand Down
6 changes: 3 additions & 3 deletions src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use loophp\collection\Operation\Intersperse;
use loophp\collection\Operation\Iterate;
use loophp\collection\Operation\Keys;
use loophp\collection\Operation\Last;
use loophp\collection\Operation\Limit;
use loophp\collection\Operation\Loop;
use loophp\collection\Operation\Map;
Expand Down Expand Up @@ -84,7 +85,6 @@
use loophp\collection\Transformation\Get;
use loophp\collection\Transformation\Has;
use loophp\collection\Transformation\Implode;
use loophp\collection\Transformation\Last;
use loophp\collection\Transformation\Nullsy;
use loophp\collection\Transformation\Reduce;
use loophp\collection\Transformation\Run;
Expand Down Expand Up @@ -467,9 +467,9 @@ public function keys(): CollectionInterface
return $this->run(new Keys());
}

public function last(?callable $callback = null, $default = null)
public function last(?callable $callback = null, int $size = 1): CollectionInterface
{
return $this->transform(new Last($callback, $default));
return $this->run(new Last($callback, $size));
}

public function limit(int $limit, int $offset = 0): CollectionInterface
Expand Down
2 changes: 1 addition & 1 deletion src/Contract/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use loophp\collection\Contract\Operation\Intersperseable;
use loophp\collection\Contract\Operation\Iterateable;
use loophp\collection\Contract\Operation\Keysable;
use loophp\collection\Contract\Operation\Lastable;
use loophp\collection\Contract\Operation\Limitable;
use loophp\collection\Contract\Operation\Loopable;
use loophp\collection\Contract\Operation\Mapable;
Expand Down Expand Up @@ -76,7 +77,6 @@
use loophp\collection\Contract\Transformation\Getable;
use loophp\collection\Contract\Transformation\Hasable;
use loophp\collection\Contract\Transformation\Implodeable;
use loophp\collection\Contract\Transformation\Lastable;
use loophp\collection\Contract\Transformation\Nullsyable;
use loophp\collection\Contract\Transformation\Reduceable;
use loophp\collection\Contract\Transformation\Runable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

declare(strict_types=1);

namespace loophp\collection\Contract\Transformation;
namespace loophp\collection\Contract\Operation;

use loophp\collection\Contract\Collection;

/**
* @psalm-template TKey
Expand All @@ -16,11 +18,7 @@ interface Lastable
*
* @psalm-param null|callable(T, TKey):(bool) $callback
*
* @param mixed|null $default
* @psalm-param T|null $default
*
* @return mixed|null
* @psalm-return T|null
* @psalm-return \loophp\collection\Contract\Collection<TKey, T>
*/
public function last(?callable $callback = null, $default = null);
public function last(?callable $callback = null, int $size = 1): Collection;
}
76 changes: 76 additions & 0 deletions src/Operation/Last.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace loophp\collection\Operation;

use Closure;
use Generator;
use Iterator;
use loophp\collection\Contract\Operation;
use loophp\collection\Transformation\Run;

/**
* @psalm-template TKey
* @psalm-template TKey of array-key
* @psalm-template T
*
* @implements Operation<TKey, T>
*/
final class Last extends AbstractOperation implements Operation
{
/**
* @var callable|Closure
* @psalm-var callable(T, TKey):(bool)|\Closure(T, TKey):(bool)
*/
private $callback;

/**
* @psalm-param \Closure(T, TKey):(bool)|callable(T, TKey):(bool)|null $callback
* @psalm-param T|null $default
*/
public function __construct(?callable $callback = null, int $size = 1)
{
$defaultCallback =
/**
* @param mixed $value
* @param mixed $key
* @psalm-param T $value
* @psalm-param TKey $key
* @psalm-param Iterator<TKey, T> $iterator
*/
static function ($value, $key, Iterator $iterator): bool {
return true;
};

$this->storage = [
'callback' => $callback ?? $defaultCallback,
'size' => $size,
];
}

public function __invoke(): Closure
{
return
/**
* @psalm-param \Iterator<TKey, T> $iterator
*
* @psalm-return \Generator<TKey, T>
*/
static function (Iterator $iterator, callable $callback, int $size): Generator {
$callback =
/**
* @param mixed $value
* @param mixed $key
* @psalm-param T $value
* @psalm-param TKey $key
* @psalm-param Iterator<TKey, T> $iterator
*/
static function ($value, $key, Iterator $iterator) use ($callback): bool {
return true === $callback($value, $key, $iterator);
};

return yield from (new Run(new Filter($callback), new Reverse(), new Limit($size)))($iterator);
};
}
}
89 changes: 0 additions & 89 deletions src/Transformation/Last.php

This file was deleted.

0 comments on commit a8cb98f

Please sign in to comment.