Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: loophp/collection
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.0.4
Choose a base ref
...
head repository: loophp/collection
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.0.5
Choose a head ref
  • 7 commits
  • 26 files changed
  • 1 contributor

Commits on Aug 20, 2019

  1. Copy the full SHA
    fd081c2 View commit details
  2. Minor update.

    drupol committed Aug 20, 2019
    Copy the full SHA
    04739ad View commit details

Commits on Aug 21, 2019

  1. Update count() method.

    drupol committed Aug 21, 2019
    Copy the full SHA
    baf96eb View commit details
  2. Add ::last() method.

    drupol committed Aug 21, 2019
    Copy the full SHA
    9ea67a4 View commit details
  3. Copy the full SHA
    e50bbfd View commit details
  4. Add return type to Closures.

    drupol committed Aug 21, 2019
    Copy the full SHA
    a2b9366 View commit details
  5. Update README.

    drupol committed Aug 21, 2019
    Copy the full SHA
    3fcbf00 View commit details
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -178,21 +178,22 @@ the methods always return the same values for the same inputs.

| Methods | Return type | Source |
| ------------- | --------------------- | -------------- |
| `all` | array | [Collection.php](./src/Collection.php)
| `all` | array | [All.php](./src/Operation/All.php)
| `append` | new Collection object | [Append.php](./src/Operation/Append.php)
| `apply` | self | [Apply.php](./src/Operation/Apply.php)
| `chunk` | new Collection object | [Chunk.php](./src/Operation/Chunk.php)
| `collapse` | new Collection object | [Collapse.php](./src/Operation/Collapse.php)
| `combine` | new Collection object | [Combine.php](./src/Operation/Combine.php)
| `count` | int | [Collection.php](./src/Collection.php)
| `count` | int | [Count.php](./src/Operation/Count.php)
| `filter` | new Collection object | [Filter.php](./src/Operation/Filter.php)
| `first` | mixed | [Collection.php](./src/Collection.php)
| `first` | mixed | [First.php](./src/Operation/First.php)
| `flatten` | new Collection object | [Flatten.php](./src/Operation/Flatten.php)
| `flip` | new Collection object | [Flip.php](./src/Operation/Flip.php)
| `forget` | new Collection object | [Forget.php](./src/Operation/Forget.php)
| `get` | mixed | [Collection.php](./src/Collection.php)
| `get` | mixed | [Get.php](./src/Operation/Get.php)
| `getIterator` | Iterator | [Collection.php](./src/Collection.php)
| `keys` | new Collection object | [Keys.php](./src/Operation/Keys.php)
| `last` | mixed | [Last.php](./src/Operation/Last.php)
| `limit` | new Collection object | [Limit.php](./src/Operation/Limit.php)
| `map` | new Collection object | [Map.php](./src/Operation/Map.php)
| `merge` | new Collection object | [Merge.php](./src/Operation/Merge.php)
@@ -204,10 +205,11 @@ the methods always return the same values for the same inputs.
| `prepend` | new Collection object | [Prepend.php](./src/Operation/Prepend.php)
| `proxy` | new Collection object | [Proxy.php](./src/Operation/Proxy.php)
| `rebase` | new Collection object | [Rebase.php](./src/Operation/Rebase.php)
| `reduce` | mixed | [Collection.php](./src/Collection.php)
| `reduce` | mixed | [Reduce.php](./src/Operation/Reduce.php)
| `run` | mixed | [Run.php](./src/Operation/Run.php)
| `skip` | new Collection object | [Skip.php](./src/Operation/Skip.php)
| `slice` | new Collection object | [Slice.php](./src/Operation/Slice.php)
| `sort ` | new Collection object | [Sort.php](./src/Operation/Sort.php)
| `walk` | new Collection object | [Walk.php](./src/Operation/Walk.php)
| `zip` | new Collection object | [Zip.php](./src/Operation/Zip.php)

29 changes: 29 additions & 0 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
@@ -472,6 +472,20 @@ static function ($value) {
->shouldBe(null);
}

public function it_can_get_the_last_item(): void
{
$this
->beConstructedThrough('with', [\range('A', 'F')]);

$this
->last()
->shouldReturn('F');

$this::with([])
->last()
->shouldReturn(null);
}

public function it_can_keys(): void
{
$this
@@ -763,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
29 changes: 24 additions & 5 deletions src/Collection.php
Original file line number Diff line number Diff line change
@@ -15,13 +15,15 @@
use drupol\collection\Operation\Collapse;
use drupol\collection\Operation\Combine;
use drupol\collection\Operation\Contains;
use drupol\collection\Operation\Count;
use drupol\collection\Operation\Filter;
use drupol\collection\Operation\First;
use drupol\collection\Operation\Flatten;
use drupol\collection\Operation\Flip;
use drupol\collection\Operation\Forget;
use drupol\collection\Operation\Get;
use drupol\collection\Operation\Keys;
use drupol\collection\Operation\Last;
use drupol\collection\Operation\Limit;
use drupol\collection\Operation\Merge;
use drupol\collection\Operation\Normalize;
@@ -37,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;
@@ -112,7 +115,7 @@ public function contains($key): bool
*/
public function count(): int
{
return \iterator_count($this->getIterator());
return $this->run(Count::with());
}

/**
@@ -126,9 +129,9 @@ public static function empty(): CollectionInterface
/**
* {@inheritdoc}
*/
public function filter(callable $callback = null): CollectionInterface
public function filter(callable ...$callbacks): CollectionInterface
{
return $this->run(Filter::with($callback));
return $this->run(Filter::with($callbacks));
}

/**
@@ -187,6 +190,14 @@ public function keys(): CollectionInterface
return $this->run(Keys::with());
}

/**
* {@inheritdoc}
*/
public function last()
{
return $this->run(Last::with());
}

/**
* {@inheritdoc}
*/
@@ -321,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.
*
@@ -357,11 +376,11 @@ public function walk(callable ...$callbacks): CollectionInterface
/**
* Create a new collection instance.
*
* @param null|array|callable|Closure|CollectionInterface|\Iterator $data
* @param array|callable|Closure|CollectionInterface|\Iterator $data
*
* @return \drupol\collection\Contract\Collection
*/
public static function with($data = []): CollectionInterface
public static function with($data): CollectionInterface
{
if ($data instanceof Closure || \is_callable($data)) {
return self::withClosure($data);
22 changes: 19 additions & 3 deletions src/Contract/Collection.php
Original file line number Diff line number Diff line change
@@ -75,11 +75,11 @@ public function count(): int;
/**
* Run a filter over each of the items.
*
* @param null|callable $callback
* @param callable ...$callbacks
*
* @return \drupol\collection\Contract\Collection
*/
public function filter(callable $callback = null): self;
public function filter(callable ...$callbacks): self;

/**
* Get the first item from the collection passing the given truth test.
@@ -142,6 +142,13 @@ public function getIterator();
*/
public function keys(): self;

/**
* Get the last item.
*
* @return mixed
*/
public function last();

/**
* Limit the first {$limit} items.
*
@@ -249,7 +256,7 @@ public function reduce(callable $callback, $initial = null);
/**
* @param \drupol\collection\Contract\Operation ...$operations
*
* @return bool|mixed
* @return bool|int|mixed
*/
public function run(Operation ...$operations);

@@ -272,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
*
3 changes: 2 additions & 1 deletion src/Operation/Append.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public function run(CollectionInterface $collection): CollectionInterface
[$items] = $this->parameters;

return Collection::with(
static function () use ($items, $collection) {
static function () use ($items, $collection): \Generator
{
foreach ($collection as $item) {
yield $item;
}
5 changes: 3 additions & 2 deletions src/Operation/Chunk.php
Original file line number Diff line number Diff line change
@@ -20,11 +20,12 @@ public function run(CollectionInterface $collection): CollectionInterface
$size = $this->parameters[0];

if (0 >= $size) {
return Collection::with();
return Collection::empty();
}

return Collection::with(
static function () use ($size, $collection) {
static function () use ($size, $collection): \Generator
{
$iterator = $collection->getIterator();

while ($iterator->valid()) {
3 changes: 2 additions & 1 deletion src/Operation/Collapse.php
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@ final class Collapse extends Operation
public function run(CollectionInterface $collection): CollectionInterface
{
return Collection::with(
static function () use ($collection) {
static function () use ($collection): \Generator
{
foreach ($collection as $item) {
if (\is_array($item) || $item instanceof CollectionInterface) {
foreach ($item as $value) {
3 changes: 2 additions & 1 deletion src/Operation/Combine.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public function run(CollectionInterface $collection): CollectionInterface
[$keys] = $this->parameters;

return Collection::with(
static function () use ($keys, $collection) {
static function () use ($keys, $collection): \Generator
{
$original = $collection->getIterator();
$keysIterator = Collection::with($keys)->getIterator();

23 changes: 23 additions & 0 deletions src/Operation/Count.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Class Count.
*
* Be careful, this will only work with finite collection sets.
*/
final class Count extends Operation
{
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection)
{
return \iterator_count($collection->getIterator());
}
}
17 changes: 10 additions & 7 deletions src/Operation/Filter.php
Original file line number Diff line number Diff line change
@@ -17,19 +17,22 @@ final class Filter extends Operation
*/
public function run(CollectionInterface $collection): CollectionInterface
{
$callback = $this->parameters[0];
[$callbacks] = $this->parameters;

if (null === $callback) {
$callback = static function ($value) {
if ([] === $callbacks) {
$callbacks[] = static function ($value) {
return $value;
};
}

return Collection::with(
static function () use ($callback, $collection) {
foreach ($collection->getIterator() as $key => $value) {
if (true === (bool) $callback($value, $key)) {
yield $key => $value;
static function () use ($callbacks, $collection): \Generator
{
foreach ($callbacks as $callback) {
foreach ($collection->getIterator() as $key => $value) {
if (true === (bool) $callback($value, $key)) {
yield $key => $value;
}
}
}
}
3 changes: 2 additions & 1 deletion src/Operation/Flatten.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public function run(CollectionInterface $collection): CollectionInterface
$depth = $this->parameters[0];

return Collection::with(
static function () use ($depth, $collection) {
static function () use ($depth, $collection): \Generator
{
$iterator = $collection->getIterator();

foreach ($iterator as $item) {
3 changes: 2 additions & 1 deletion src/Operation/Flip.php
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@ final class Flip extends Operation
public function run(CollectionInterface $collection): CollectionInterface
{
return Collection::with(
static function () use ($collection) {
static function () use ($collection): \Generator
{
foreach ($collection as $key => $value) {
yield $value => $key;
}
3 changes: 2 additions & 1 deletion src/Operation/Forget.php
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ public function run(CollectionInterface $collection): CollectionInterface
[$keys] = $this->parameters;

return Collection::with(
static function () use ($keys, $collection) {
static function () use ($keys, $collection): \Generator
{
$keys = \array_flip($keys);

foreach ($collection->getIterator() as $key => $value) {
3 changes: 2 additions & 1 deletion src/Operation/Keys.php
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@ final class Keys extends Operation
public function run(CollectionInterface $collection): CollectionInterface
{
return Collection::with(
static function () use ($collection) {
static function () use ($collection): \Generator
{
foreach ($collection as $key => $value) {
yield $key;
}
35 changes: 35 additions & 0 deletions src/Operation/Last.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace drupol\collection\Operation;

use drupol\collection\Contract\Collection as CollectionInterface;

/**
* Class Last.
*
* Be careful, this will only work with finite collection sets.
*/
final class Last extends Operation
{
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection)
{
/** @var \Iterator $iterator */
$iterator = $collection->getIterator();

$iterator->rewind();

$last = $iterator->current();

while (true === $iterator->valid()) {
$last = $iterator->current();
$iterator->next();
}

return $last;
}
}
Loading