Skip to content

Commit

Permalink
Add more collection methods: unique, transform, take, slice, splice, …
Browse files Browse the repository at this point in the history
…reject, and chunk.
  • Loading branch information
zachleigh committed Apr 21, 2016
1 parent c0972d5 commit b8df714
Show file tree
Hide file tree
Showing 3 changed files with 384 additions and 7 deletions.
135 changes: 135 additions & 0 deletions src/Classes/Collection.php
Expand Up @@ -24,6 +24,24 @@ public function all()
{
return $this->words;
}

/**
* Chunk the underlying collection array.
*
* @param int $size
*
* @return static
*/
public function chunk($size)
{
$chunks = [];

foreach (array_chunk($this->words, $size, true) as $chunk) {
$chunks[] = new static($this->text, $chunk, $this->pluginData);
}

return new static($this->text, $chunks, $this->pluginData);
}

/**
* Count the number of items on the object.
Expand Down Expand Up @@ -303,6 +321,25 @@ public function push($value)
return $this;
}

/**
* Create a collection of all elements that do not pass a given truth test.
*
* @param callable|mixed $callback
*
* @return static
*/
public function reject($callback)
{
if ($this->useAsCallable($callback)) {
return $this->filter(function ($value, $key) use ($callback) {
return ! $callback($value, $key);
});
}
return $this->filter(function ($item) use ($callback) {
return $item != $callback;
});
}

/**
* Get and remove the first item from the collection.
*
Expand All @@ -312,4 +349,102 @@ public function shift()
{
return array_shift($this->words);
}

/**
* Slice the underlying collection array.
*
* @param int $offset
* @param int $length
*
* @return static
*/
public function slice($offset, $length = null)
{
return new static($this->text, array_slice($this->words, $offset, $length, true), $this->pluginData);
}

/**
* Splice a portion of the underlying collection array.
*
* @param int $offset
* @param int|null $length
* @param mixed $replacement
*
* @return static
*/
public function splice($offset, $length = null, $replacement = [])
{
if (func_num_args() == 1) {
return new static($this->text, array_splice($this->words, $offset), $this->pluginData);
}

return new static($this->text, array_splice($this->words, $offset, $length, $replacement), $this->pluginData);
}

/**
* Take the first or last {$limit} items.
*
* @param int $limit
*
* @return static
*/
public function take($limit)
{
if ($limit < 0) {
return $this->slice($limit, abs($limit));
}

return $this->slice(0, $limit);
}

/**
* Get the collection of items as a plain array.
*
* @return array
*/
public function toArray()
{
return array_map(function ($value) {
return $value instanceof Arrayable ? $value->toArray() : $value;
}, $this->words);
}

/**
* Transform each item in the collection using a callback.
*
* @param callable $callback
*
* @return $this
*/
public function transform(callable $callback)
{
$this->words = $this->map($callback)->all();

return $this;
}

/**
* Return only unique items from the collection array.
*
* @param string|callable|null $key
* @return static
*/
public function unique($key = null)
{
if (is_null($key)) {
return new static($this->text, array_unique($this->words, SORT_REGULAR), $this->pluginData);
}

$key = $this->valueRetriever($key);

$exists = [];

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

$exists[] = $id;
});
}
}
30 changes: 30 additions & 0 deletions src/Helpers/Arr.php
Expand Up @@ -350,6 +350,18 @@ protected function explodePluckParameters($value, $key)
return [$value, $key];
}

/**
* Determine if the given value is callable, but not a string.
*
* @param mixed $value
*
* @return bool
*/
protected function useAsCallable($value)
{
return ! is_string($value) && is_callable($value);
}

/**
* Return the default value of the given value.
*
Expand All @@ -360,4 +372,22 @@ protected function value($value)
{
return $value instanceof Closure ? $value() : $value;
}

/**
* Get a value retrieving callback.
*
* @param string $value
*
* @return callable
*/
protected function valueRetriever($value)
{
if ($this->useAsCallable($value)) {
return $value;
}

return function ($item) use ($value) {
return $this->dataGet($item, $value);
};
}
}

0 comments on commit b8df714

Please sign in to comment.