Arr.php000064400000042322147536117460006022 0ustar00all(); } elseif (! is_array($values)) { continue; } $results[] = $values; } return array_merge([], ...$results); } /** * Cross join the given arrays, returning all possible permutations. * * @param iterable ...$arrays * @return array */ public static function crossJoin(...$arrays) { $results = [[]]; foreach ($arrays as $index => $array) { $append = []; foreach ($results as $product) { foreach ($array as $item) { $product[$index] = $item; $append[] = $product; } } $results = $append; } return $results; } /** * Divide an array into two arrays. One with keys and the other with values. * * @param array $array * @return array */ public static function divide($array) { return [array_keys($array), array_values($array)]; } /** * Flatten a multi-dimensional associative array with dots. * * @param iterable $array * @param string $prepend * @return array */ public static function dot($array, $prepend = '') { $results = []; foreach ($array as $key => $value) { if (is_array($value) && ! empty($value)) { $results = array_merge($results, static::dot($value, $prepend.$key.'.')); } else { $results[$prepend.$key] = $value; } } return $results; } /** * Get all of the given array except for a specified array of keys. * * @param array $array * @param array|string $keys * @return array */ public static function except($array, $keys) { static::forget($array, $keys); return $array; } /** * Determine if the given key exists in the provided array. * * @param \ArrayAccess|array $array * @param string|int $key * @return bool */ public static function exists($array, $key) { if ($array instanceof Enumerable) { return $array->has($key); } if ($array instanceof ArrayAccess) { return $array->offsetExists($key); } return array_key_exists($key, $array); } /** * Return the first element in an array passing a given truth test. * * @param iterable $array * @param callable|null $callback * @param mixed $default * @return mixed */ public static function first($array, callable $callback = null, $default = null) { if (is_null($callback)) { if (empty($array)) { return value($default); } foreach ($array as $item) { return $item; } } foreach ($array as $key => $value) { if ($callback($value, $key)) { return $value; } } return value($default); } /** * Return the last element in an array passing a given truth test. * * @param array $array * @param callable|null $callback * @param mixed $default * @return mixed */ public static function last($array, callable $callback = null, $default = null) { if (is_null($callback)) { return empty($array) ? value($default) : end($array); } return static::first(array_reverse($array, true), $callback, $default); } /** * Flatten a multi-dimensional array into a single level. * * @param iterable $array * @param int $depth * @return array */ public static function flatten($array, $depth = INF) { $result = []; foreach ($array as $item) { $item = $item instanceof Collection ? $item->all() : $item; if (! is_array($item)) { $result[] = $item; } else { $values = $depth === 1 ? array_values($item) : static::flatten($item, $depth - 1); foreach ($values as $value) { $result[] = $value; } } } return $result; } /** * Remove one or many array items from a given array using "dot" notation. * * @param array $array * @param array|string $keys * @return void */ public static function forget(&$array, $keys) { $original = &$array; $keys = (array) $keys; if (count($keys) === 0) { return; } foreach ($keys as $key) { // if the exact key exists in the top-level, remove it if (static::exists($array, $key)) { unset($array[$key]); continue; } $parts = explode('.', $key); // clean up before each pass $array = &$original; while (count($parts) > 1) { $part = array_shift($parts); if (isset($array[$part]) && is_array($array[$part])) { $array = &$array[$part]; } else { continue 2; } } unset($array[array_shift($parts)]); } } /** * Get an item from an array using "dot" notation. * * @param \ArrayAccess|array $array * @param string|int|null $key * @param mixed $default * @return mixed */ public static function get($array, $key, $default = null) { if (! static::accessible($array)) { return value($default); } if (is_null($key)) { return $array; } if (static::exists($array, $key)) { return $array[$key]; } if (strpos($key, '.') === false) { return $array[$key] ?? value($default); } foreach (explode('.', $key) as $segment) { if (static::accessible($array) && static::exists($array, $segment)) { $array = $array[$segment]; } else { return value($default); } } return $array; } /** * Check if an item or items exist in an array using "dot" notation. * * @param \ArrayAccess|array $array * @param string|array $keys * @return bool */ public static function has($array, $keys) { $keys = (array) $keys; if (! $array || $keys === []) { return false; } foreach ($keys as $key) { $subKeyArray = $array; if (static::exists($array, $key)) { continue; } foreach (explode('.', $key) as $segment) { if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) { $subKeyArray = $subKeyArray[$segment]; } else { return false; } } } return true; } /** * Determine if any of the keys exist in an array using "dot" notation. * * @param \ArrayAccess|array $array * @param string|array $keys * @return bool */ public static function hasAny($array, $keys) { if (is_null($keys)) { return false; } $keys = (array) $keys; if (! $array) { return false; } if ($keys === []) { return false; } foreach ($keys as $key) { if (static::has($array, $key)) { return true; } } return false; } /** * Determines if an array is associative. * * An array is "associative" if it doesn't have sequential numerical keys beginning with zero. * * @param array $array * @return bool */ public static function isAssoc(array $array) { $keys = array_keys($array); return array_keys($keys) !== $keys; } /** * Determines if an array is a list. * * An array is a "list" if all array keys are sequential integers starting from 0 with no gaps in between. * * @param array $array * @return bool */ public static function isList($array) { return ! self::isAssoc($array); } /** * Get a subset of the items from the given array. * * @param array $array * @param array|string $keys * @return array */ public static function only($array, $keys) { return array_intersect_key($array, array_flip((array) $keys)); } /** * Pluck an array of values from an array. * * @param iterable $array * @param string|array|int|null $value * @param string|array|null $key * @return array */ public static function pluck($array, $value, $key = null) { $results = []; [$value, $key] = static::explodePluckParameters($value, $key); foreach ($array as $item) { $itemValue = data_get($item, $value); // If the key is "null", we will just append the value to the array and keep // looping. Otherwise we will key the array using the value of the key we // received from the developer. Then we'll return the final array form. if (is_null($key)) { $results[] = $itemValue; } else { $itemKey = data_get($item, $key); if (is_object($itemKey) && method_exists($itemKey, '__toString')) { $itemKey = (string) $itemKey; } $results[$itemKey] = $itemValue; } } return $results; } /** * Explode the "value" and "key" arguments passed to "pluck". * * @param string|array $value * @param string|array|null $key * @return array */ protected static function explodePluckParameters($value, $key) { $value = is_string($value) ? explode('.', $value) : $value; $key = is_null($key) || is_array($key) ? $key : explode('.', $key); return [$value, $key]; } /** * Push an item onto the beginning of an array. * * @param array $array * @param mixed $value * @param mixed $key * @return array */ public static function prepend($array, $value, $key = null) { if (func_num_args() == 2) { array_unshift($array, $value); } else { $array = [$key => $value] + $array; } return $array; } /** * Get a value from the array, and remove it. * * @param array $array * @param string $key * @param mixed $default * @return mixed */ public static function pull(&$array, $key, $default = null) { $value = static::get($array, $key, $default); static::forget($array, $key); return $value; } /** * Convert the array into a query string. * * @param array $array * @return string */ public static function query($array) { return http_build_query($array, '', '&', PHP_QUERY_RFC3986); } /** * Get one or a specified number of random values from an array. * * @param array $array * @param int|null $number * @param bool|false $preserveKeys * @return mixed * * @throws \InvalidArgumentException */ public static function random($array, $number = null, $preserveKeys = false) { $requested = is_null($number) ? 1 : $number; $count = count($array); if ($requested > $count) { throw new InvalidArgumentException( "You requested {$requested} items, but there are only {$count} items available." ); } if (is_null($number)) { return $array[array_rand($array)]; } if ((int) $number === 0) { return []; } $keys = array_rand($array, $number); $results = []; if ($preserveKeys) { foreach ((array) $keys as $key) { $results[$key] = $array[$key]; } } else { foreach ((array) $keys as $key) { $results[] = $array[$key]; } } return $results; } /** * Set an array item to a given value using "dot" notation. * * If no key is given to the method, the entire array will be replaced. * * @param array $array * @param string|null $key * @param mixed $value * @return array */ public static function set(&$array, $key, $value) { if (is_null($key)) { return $array = $value; } $keys = explode('.', $key); foreach ($keys as $i => $key) { if (count($keys) === 1) { break; } unset($keys[$i]); // If the key doesn't exist at this depth, we will just create an empty array // to hold the next value, allowing us to create the arrays to hold final // values at the correct depth. Then we'll keep digging into the array. if (! isset($array[$key]) || ! is_array($array[$key])) { $array[$key] = []; } $array = &$array[$key]; } $array[array_shift($keys)] = $value; return $array; } /** * Shuffle the given array and return the result. * * @param array $array * @param int|null $seed * @return array */ public static function shuffle($array, $seed = null) { if (is_null($seed)) { shuffle($array); } else { mt_srand($seed); shuffle($array); mt_srand(); } return $array; } /** * Sort the array using the given callback or "dot" notation. * * @param array $array * @param callable|array|string|null $callback * @return array */ public static function sort($array, $callback = null) { return Collection::make($array)->sortBy($callback)->all(); } /** * Recursively sort an array by keys and values. * * @param array $array * @param int $options * @param bool $descending * @return array */ public static function sortRecursive($array, $options = SORT_REGULAR, $descending = false) { foreach ($array as &$value) { if (is_array($value)) { $value = static::sortRecursive($value, $options, $descending); } } if (static::isAssoc($array)) { $descending ? krsort($array, $options) : ksort($array, $options); } else { $descending ? rsort($array, $options) : sort($array, $options); } return $array; } /** * Conditionally compile classes from an array into a CSS class list. * * @param array $array * @return string */ public static function toCssClasses($array) { $classList = static::wrap($array); $classes = []; foreach ($classList as $class => $constraint) { if (is_numeric($class)) { $classes[] = $constraint; } elseif ($constraint) { $classes[] = $class; } } return implode(' ', $classes); } /** * Filter the array using the given callback. * * @param array $array * @param callable $callback * @return array */ public static function where($array, callable $callback) { return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH); } /** * If the given value is not an array and not null, wrap it in one. * * @param mixed $value * @return array */ public static function wrap($value) { if (is_null($value)) { return []; } return is_array($value) ? $value : [$value]; } } Collection.php000064400000112617147536117460007376 0ustar00items = $this->getArrayableItems($items); } /** * Create a collection with the given range. * * @param int $from * @param int $to * @return static */ public static function range($from, $to) { return new static(range($from, $to)); } /** * Get all of the items in the collection. * * @return array */ public function all() { return $this->items; } /** * Get a lazy collection for the items in this collection. * * @return \Illuminate\Support\LazyCollection */ public function lazy() { return new LazyCollection($this->items); } /** * Get the average value of a given key. * * @param callable|string|null $callback * @return mixed */ public function avg($callback = null) { $callback = $this->valueRetriever($callback); $items = $this->map(function ($value) use ($callback) { return $callback($value); })->filter(function ($value) { return ! is_null($value); }); if ($count = $items->count()) { return $items->sum() / $count; } } /** * Get the median of a given key. * * @param string|array|null $key * @return mixed */ public function median($key = null) { $values = (isset($key) ? $this->pluck($key) : $this) ->filter(function ($item) { return ! is_null($item); })->sort()->values(); $count = $values->count(); if ($count === 0) { return; } $middle = (int) ($count / 2); if ($count % 2) { return $values->get($middle); } return (new static([ $values->get($middle - 1), $values->get($middle), ]))->average(); } /** * Get the mode of a given key. * * @param string|array|null $key * @return array|null */ public function mode($key = null) { if ($this->count() === 0) { return; } $collection = isset($key) ? $this->pluck($key) : $this; $counts = new static; $collection->each(function ($value) use ($counts) { $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1; }); $sorted = $counts->sort(); $highestValue = $sorted->last(); return $sorted->filter(function ($value) use ($highestValue) { return $value == $highestValue; })->sort()->keys()->all(); } /** * Collapse the collection of items into a single array. * * @return static */ public function collapse() { return new static(Arr::collapse($this->items)); } /** * Determine if an item exists in the collection. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return bool */ public function contains($key, $operator = null, $value = null) { if (func_num_args() === 1) { if ($this->useAsCallable($key)) { $placeholder = new stdClass; return $this->first($key, $placeholder) !== $placeholder; } return in_array($key, $this->items); } return $this->contains($this->operatorForWhere(...func_get_args())); } /** * Cross join with the given lists, returning all possible permutations. * * @param mixed ...$lists * @return static */ public function crossJoin(...$lists) { return new static(Arr::crossJoin( $this->items, ...array_map([$this, 'getArrayableItems'], $lists) )); } /** * Get the items in the collection that are not present in the given items. * * @param mixed $items * @return static */ public function diff($items) { return new static(array_diff($this->items, $this->getArrayableItems($items))); } /** * Get the items in the collection that are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffUsing($items, callable $callback) { return new static(array_udiff($this->items, $this->getArrayableItems($items), $callback)); } /** * Get the items in the collection whose keys and values are not present in the given items. * * @param mixed $items * @return static */ public function diffAssoc($items) { return new static(array_diff_assoc($this->items, $this->getArrayableItems($items))); } /** * Get the items in the collection whose keys and values are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffAssocUsing($items, callable $callback) { return new static(array_diff_uassoc($this->items, $this->getArrayableItems($items), $callback)); } /** * Get the items in the collection whose keys are not present in the given items. * * @param mixed $items * @return static */ public function diffKeys($items) { return new static(array_diff_key($this->items, $this->getArrayableItems($items))); } /** * Get the items in the collection whose keys are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffKeysUsing($items, callable $callback) { return new static(array_diff_ukey($this->items, $this->getArrayableItems($items), $callback)); } /** * Retrieve duplicate items from the collection. * * @param callable|string|null $callback * @param bool $strict * @return static */ public function duplicates($callback = null, $strict = false) { $items = $this->map($this->valueRetriever($callback)); $uniqueItems = $items->unique(null, $strict); $compare = $this->duplicateComparator($strict); $duplicates = new static; foreach ($items as $key => $value) { if ($uniqueItems->isNotEmpty() && $compare($value, $uniqueItems->first())) { $uniqueItems->shift(); } else { $duplicates[$key] = $value; } } return $duplicates; } /** * Retrieve duplicate items from the collection using strict comparison. * * @param callable|string|null $callback * @return static */ public function duplicatesStrict($callback = null) { return $this->duplicates($callback, true); } /** * Get the comparison function to detect duplicates. * * @param bool $strict * @return \Closure */ protected function duplicateComparator($strict) { if ($strict) { return function ($a, $b) { return $a === $b; }; } return function ($a, $b) { return $a == $b; }; } /** * Get all items except for those with the specified keys. * * @param \Illuminate\Support\Collection|mixed $keys * @return static */ public function except($keys) { if ($keys instanceof Enumerable) { $keys = $keys->all(); } elseif (! is_array($keys)) { $keys = func_get_args(); } return new static(Arr::except($this->items, $keys)); } /** * Run a filter over each of the items. * * @param callable|null $callback * @return static */ public function filter(callable $callback = null) { if ($callback) { return new static(Arr::where($this->items, $callback)); } return new static(array_filter($this->items)); } /** * Get the first item from the collection passing the given truth test. * * @param callable|null $callback * @param mixed $default * @return mixed */ public function first(callable $callback = null, $default = null) { return Arr::first($this->items, $callback, $default); } /** * Get a flattened array of the items in the collection. * * @param int $depth * @return static */ public function flatten($depth = INF) { return new static(Arr::flatten($this->items, $depth)); } /** * Flip the items in the collection. * * @return static */ public function flip() { return new static(array_flip($this->items)); } /** * Remove an item from the collection by key. * * @param string|array $keys * @return $this */ public function forget($keys) { foreach ((array) $keys as $key) { $this->offsetUnset($key); } return $this; } /** * Get an item from the collection by key. * * @param mixed $key * @param mixed $default * @return mixed */ public function get($key, $default = null) { if (array_key_exists($key, $this->items)) { return $this->items[$key]; } return value($default); } /** * Group an associative array by a field or using a callback. * * @param array|callable|string $groupBy * @param bool $preserveKeys * @return static */ public function groupBy($groupBy, $preserveKeys = false) { if (! $this->useAsCallable($groupBy) && is_array($groupBy)) { $nextGroups = $groupBy; $groupBy = array_shift($nextGroups); } $groupBy = $this->valueRetriever($groupBy); $results = []; foreach ($this->items as $key => $value) { $groupKeys = $groupBy($value, $key); if (! is_array($groupKeys)) { $groupKeys = [$groupKeys]; } foreach ($groupKeys as $groupKey) { $groupKey = is_bool($groupKey) ? (int) $groupKey : $groupKey; if (! array_key_exists($groupKey, $results)) { $results[$groupKey] = new static; } $results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value); } } $result = new static($results); if (! empty($nextGroups)) { return $result->map->groupBy($nextGroups, $preserveKeys); } return $result; } /** * Key an associative array by a field or using a callback. * * @param callable|string $keyBy * @return static */ public function keyBy($keyBy) { $keyBy = $this->valueRetriever($keyBy); $results = []; foreach ($this->items as $key => $item) { $resolvedKey = $keyBy($item, $key); if (is_object($resolvedKey)) { $resolvedKey = (string) $resolvedKey; } $results[$resolvedKey] = $item; } return new static($results); } /** * Determine if an item exists in the collection by key. * * @param mixed $key * @return bool */ public function has($key) { $keys = is_array($key) ? $key : func_get_args(); foreach ($keys as $value) { if (! array_key_exists($value, $this->items)) { return false; } } return true; } /** * Determine if any of the keys exist in the collection. * * @param mixed $key * @return bool */ public function hasAny($key) { if ($this->isEmpty()) { return false; } $keys = is_array($key) ? $key : func_get_args(); foreach ($keys as $value) { if ($this->has($value)) { return true; } } return false; } /** * Concatenate values of a given key as a string. * * @param string $value * @param string|null $glue * @return string */ public function implode($value, $glue = null) { $first = $this->first(); if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) { return implode($glue ?? '', $this->pluck($value)->all()); } return implode($value ?? '', $this->items); } /** * Intersect the collection with the given items. * * @param mixed $items * @return static */ public function intersect($items) { return new static(array_intersect($this->items, $this->getArrayableItems($items))); } /** * Intersect the collection with the given items by key. * * @param mixed $items * @return static */ public function intersectByKeys($items) { return new static(array_intersect_key( $this->items, $this->getArrayableItems($items) )); } /** * Determine if the collection is empty or not. * * @return bool */ public function isEmpty() { return empty($this->items); } /** * Determine if the collection contains a single item. * * @return bool */ public function containsOneItem() { return $this->count() === 1; } /** * Join all items from the collection using a string. The final items can use a separate glue string. * * @param string $glue * @param string $finalGlue * @return string */ public function join($glue, $finalGlue = '') { if ($finalGlue === '') { return $this->implode($glue); } $count = $this->count(); if ($count === 0) { return ''; } if ($count === 1) { return $this->last(); } $collection = new static($this->items); $finalItem = $collection->pop(); return $collection->implode($glue).$finalGlue.$finalItem; } /** * Get the keys of the collection items. * * @return static */ public function keys() { return new static(array_keys($this->items)); } /** * Get the last item from the collection. * * @param callable|null $callback * @param mixed $default * @return mixed */ public function last(callable $callback = null, $default = null) { return Arr::last($this->items, $callback, $default); } /** * Get the values of a given key. * * @param string|array|int|null $value * @param string|null $key * @return static */ public function pluck($value, $key = null) { return new static(Arr::pluck($this->items, $value, $key)); } /** * Run a map over each of the items. * * @param callable $callback * @return static */ public function map(callable $callback) { $keys = array_keys($this->items); $items = array_map($callback, $this->items, $keys); return new static(array_combine($keys, $items)); } /** * Run a dictionary map over the items. * * The callback should return an associative array with a single key/value pair. * * @param callable $callback * @return static */ public function mapToDictionary(callable $callback) { $dictionary = []; foreach ($this->items as $key => $item) { $pair = $callback($item, $key); $key = key($pair); $value = reset($pair); if (! isset($dictionary[$key])) { $dictionary[$key] = []; } $dictionary[$key][] = $value; } return new static($dictionary); } /** * Run an associative map over each of the items. * * The callback should return an associative array with a single key/value pair. * * @param callable $callback * @return static */ public function mapWithKeys(callable $callback) { $result = []; foreach ($this->items as $key => $value) { $assoc = $callback($value, $key); foreach ($assoc as $mapKey => $mapValue) { $result[$mapKey] = $mapValue; } } return new static($result); } /** * Merge the collection with the given items. * * @param mixed $items * @return static */ public function merge($items) { return new static(array_merge($this->items, $this->getArrayableItems($items))); } /** * Recursively merge the collection with the given items. * * @param mixed $items * @return static */ public function mergeRecursive($items) { return new static(array_merge_recursive($this->items, $this->getArrayableItems($items))); } /** * Create a collection by using this collection for keys and another for its values. * * @param mixed $values * @return static */ public function combine($values) { return new static(array_combine($this->all(), $this->getArrayableItems($values))); } /** * Union the collection with the given items. * * @param mixed $items * @return static */ public function union($items) { return new static($this->items + $this->getArrayableItems($items)); } /** * Create a new collection consisting of every n-th element. * * @param int $step * @param int $offset * @return static */ public function nth($step, $offset = 0) { $new = []; $position = 0; foreach ($this->items as $item) { if ($position % $step === $offset) { $new[] = $item; } $position++; } return new static($new); } /** * Get the items with the specified keys. * * @param mixed $keys * @return static */ public function only($keys) { if (is_null($keys)) { return new static($this->items); } if ($keys instanceof Enumerable) { $keys = $keys->all(); } $keys = is_array($keys) ? $keys : func_get_args(); return new static(Arr::only($this->items, $keys)); } /** * Get and remove the last N items from the collection. * * @param int $count * @return mixed */ public function pop($count = 1) { if ($count === 1) { return array_pop($this->items); } if ($this->isEmpty()) { return new static; } $results = []; $collectionCount = $this->count(); foreach (range(1, min($count, $collectionCount)) as $item) { array_push($results, array_pop($this->items)); } return new static($results); } /** * Push an item onto the beginning of the collection. * * @param mixed $value * @param mixed $key * @return $this */ public function prepend($value, $key = null) { $this->items = Arr::prepend($this->items, ...func_get_args()); return $this; } /** * Push one or more items onto the end of the collection. * * @param mixed $values * @return $this */ public function push(...$values) { foreach ($values as $value) { $this->items[] = $value; } return $this; } /** * Push all of the given items onto the collection. * * @param iterable $source * @return static */ public function concat($source) { $result = new static($this); foreach ($source as $item) { $result->push($item); } return $result; } /** * Get and remove an item from the collection. * * @param mixed $key * @param mixed $default * @return mixed */ public function pull($key, $default = null) { return Arr::pull($this->items, $key, $default); } /** * Put an item in the collection by key. * * @param mixed $key * @param mixed $value * @return $this */ public function put($key, $value) { $this->offsetSet($key, $value); return $this; } /** * Get one or a specified number of items randomly from the collection. * * @param int|null $number * @return static|mixed * * @throws \InvalidArgumentException */ public function random($number = null) { if (is_null($number)) { return Arr::random($this->items); } return new static(Arr::random($this->items, $number)); } /** * Replace the collection items with the given items. * * @param mixed $items * @return static */ public function replace($items) { return new static(array_replace($this->items, $this->getArrayableItems($items))); } /** * Recursively replace the collection items with the given items. * * @param mixed $items * @return static */ public function replaceRecursive($items) { return new static(array_replace_recursive($this->items, $this->getArrayableItems($items))); } /** * Reverse items order. * * @return static */ public function reverse() { return new static(array_reverse($this->items, true)); } /** * Search the collection for a given value and return the corresponding key if successful. * * @param mixed $value * @param bool $strict * @return mixed */ public function search($value, $strict = false) { if (! $this->useAsCallable($value)) { return array_search($value, $this->items, $strict); } foreach ($this->items as $key => $item) { if ($value($item, $key)) { return $key; } } return false; } /** * Get and remove the first N items from the collection. * * @param int $count * @return mixed */ public function shift($count = 1) { if ($count === 1) { return array_shift($this->items); } if ($this->isEmpty()) { return new static; } $results = []; $collectionCount = $this->count(); foreach (range(1, min($count, $collectionCount)) as $item) { array_push($results, array_shift($this->items)); } return new static($results); } /** * Shuffle the items in the collection. * * @param int|null $seed * @return static */ public function shuffle($seed = null) { return new static(Arr::shuffle($this->items, $seed)); } /** * Create chunks representing a "sliding window" view of the items in the collection. * * @param int $size * @param int $step * @return static */ public function sliding($size = 2, $step = 1) { $chunks = floor(($this->count() - $size) / $step) + 1; return static::times($chunks, function ($number) use ($size, $step) { return $this->slice(($number - 1) * $step, $size); }); } /** * Skip the first {$count} items. * * @param int $count * @return static */ public function skip($count) { return $this->slice($count); } /** * Skip items in the collection until the given condition is met. * * @param mixed $value * @return static */ public function skipUntil($value) { return new static($this->lazy()->skipUntil($value)->all()); } /** * Skip items in the collection while the given condition is met. * * @param mixed $value * @return static */ public function skipWhile($value) { return new static($this->lazy()->skipWhile($value)->all()); } /** * Slice the underlying collection array. * * @param int $offset * @param int|null $length * @return static */ public function slice($offset, $length = null) { return new static(array_slice($this->items, $offset, $length, true)); } /** * Split a collection into a certain number of groups. * * @param int $numberOfGroups * @return static */ public function split($numberOfGroups) { if ($this->isEmpty()) { return new static; } $groups = new static; $groupSize = floor($this->count() / $numberOfGroups); $remain = $this->count() % $numberOfGroups; $start = 0; for ($i = 0; $i < $numberOfGroups; $i++) { $size = $groupSize; if ($i < $remain) { $size++; } if ($size) { $groups->push(new static(array_slice($this->items, $start, $size))); $start += $size; } } return $groups; } /** * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups * @return static */ public function splitIn($numberOfGroups) { return $this->chunk(ceil($this->count() / $numberOfGroups)); } /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return mixed * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException */ public function sole($key = null, $operator = null, $value = null) { $filter = func_num_args() > 1 ? $this->operatorForWhere(...func_get_args()) : $key; $items = $this->when($filter)->filter($filter); if ($items->isEmpty()) { throw new ItemNotFoundException; } if ($items->count() > 1) { throw new MultipleItemsFoundException; } return $items->first(); } /** * Get the first item in the collection but throw an exception if no matching items exist. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return mixed * * @throws \Illuminate\Support\ItemNotFoundException */ public function firstOrFail($key = null, $operator = null, $value = null) { $filter = func_num_args() > 1 ? $this->operatorForWhere(...func_get_args()) : $key; $placeholder = new stdClass(); $item = $this->first($filter, $placeholder); if ($item === $placeholder) { throw new ItemNotFoundException; } return $item; } /** * Chunk the collection into chunks of the given size. * * @param int $size * @return static */ public function chunk($size) { if ($size <= 0) { return new static; } $chunks = []; foreach (array_chunk($this->items, $size, true) as $chunk) { $chunks[] = new static($chunk); } return new static($chunks); } /** * Chunk the collection into chunks with a callback. * * @param callable $callback * @return static */ public function chunkWhile(callable $callback) { return new static( $this->lazy()->chunkWhile($callback)->mapInto(static::class) ); } /** * Sort through each item with a callback. * * @param callable|int|null $callback * @return static */ public function sort($callback = null) { $items = $this->items; $callback && is_callable($callback) ? uasort($items, $callback) : asort($items, $callback ?? SORT_REGULAR); return new static($items); } /** * Sort items in descending order. * * @param int $options * @return static */ public function sortDesc($options = SORT_REGULAR) { $items = $this->items; arsort($items, $options); return new static($items); } /** * Sort the collection using the given callback. * * @param callable|array|string $callback * @param int $options * @param bool $descending * @return static */ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) { if (is_array($callback) && ! is_callable($callback)) { return $this->sortByMany($callback); } $results = []; $callback = $this->valueRetriever($callback); // First we will loop through the items and get the comparator from a callback // function which we were given. Then, we will sort the returned values and // and grab the corresponding values for the sorted keys from this array. foreach ($this->items as $key => $value) { $results[$key] = $callback($value, $key); } $descending ? arsort($results, $options) : asort($results, $options); // Once we have sorted all of the keys in the array, we will loop through them // and grab the corresponding model so we can set the underlying items list // to the sorted version. Then we'll just return the collection instance. foreach (array_keys($results) as $key) { $results[$key] = $this->items[$key]; } return new static($results); } /** * Sort the collection using multiple comparisons. * * @param array $comparisons * @return static */ protected function sortByMany(array $comparisons = []) { $items = $this->items; usort($items, function ($a, $b) use ($comparisons) { foreach ($comparisons as $comparison) { $comparison = Arr::wrap($comparison); $prop = $comparison[0]; $ascending = Arr::get($comparison, 1, true) === true || Arr::get($comparison, 1, true) === 'asc'; $result = 0; if (is_callable($prop)) { $result = $prop($a, $b); } else { $values = [data_get($a, $prop), data_get($b, $prop)]; if (! $ascending) { $values = array_reverse($values); } $result = $values[0] <=> $values[1]; } if ($result === 0) { continue; } return $result; } }); return new static($items); } /** * Sort the collection in descending order using the given callback. * * @param callable|string $callback * @param int $options * @return static */ public function sortByDesc($callback, $options = SORT_REGULAR) { return $this->sortBy($callback, $options, true); } /** * Sort the collection keys. * * @param int $options * @param bool $descending * @return static */ public function sortKeys($options = SORT_REGULAR, $descending = false) { $items = $this->items; $descending ? krsort($items, $options) : ksort($items, $options); return new static($items); } /** * Sort the collection keys in descending order. * * @param int $options * @return static */ public function sortKeysDesc($options = SORT_REGULAR) { return $this->sortKeys($options, true); } /** * 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(array_splice($this->items, $offset)); } return new static(array_splice($this->items, $offset, $length, $replacement)); } /** * 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); } /** * Take items in the collection until the given condition is met. * * @param mixed $value * @return static */ public function takeUntil($value) { return new static($this->lazy()->takeUntil($value)->all()); } /** * Take items in the collection while the given condition is met. * * @param mixed $value * @return static */ public function takeWhile($value) { return new static($this->lazy()->takeWhile($value)->all()); } /** * Transform each item in the collection using a callback. * * @param callable $callback * @return $this */ public function transform(callable $callback) { $this->items = $this->map($callback)->all(); return $this; } /** * Return only unique items from the collection array. * * @param string|callable|null $key * @param bool $strict * @return static */ public function unique($key = null, $strict = false) { $callback = $this->valueRetriever($key); $exists = []; return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { if (in_array($id = $callback($item, $key), $exists, $strict)) { return true; } $exists[] = $id; }); } /** * Reset the keys on the underlying array. * * @return static */ public function values() { return new static(array_values($this->items)); } /** * Zip the collection together with one or more arrays. * * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * * @param mixed ...$items * @return static */ public function zip($items) { $arrayableItems = array_map(function ($items) { return $this->getArrayableItems($items); }, func_get_args()); $params = array_merge([function () { return new static(func_get_args()); }, $this->items], $arrayableItems); return new static(array_map(...$params)); } /** * Pad collection to the specified length with a value. * * @param int $size * @param mixed $value * @return static */ public function pad($size, $value) { return new static(array_pad($this->items, $size, $value)); } /** * Get an iterator for the items. * * @return \ArrayIterator */ #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->items); } /** * Count the number of items in the collection. * * @return int */ #[\ReturnTypeWillChange] public function count() { return count($this->items); } /** * Count the number of items in the collection by a field or using a callback. * * @param callable|string $countBy * @return static */ public function countBy($countBy = null) { return new static($this->lazy()->countBy($countBy)->all()); } /** * Add an item to the collection. * * @param mixed $item * @return $this */ public function add($item) { $this->items[] = $item; return $this; } /** * Get a base Support collection instance from this collection. * * @return \Illuminate\Support\Collection */ public function toBase() { return new self($this); } /** * Determine if an item exists at an offset. * * @param mixed $key * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($key) { return isset($this->items[$key]); } /** * Get an item at a given offset. * * @param mixed $key * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->items[$key]; } /** * Set the item at a given offset. * * @param mixed $key * @param mixed $value * @return void */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { if (is_null($key)) { $this->items[] = $value; } else { $this->items[$key] = $value; } } /** * Unset the item at a given offset. * * @param string $key * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($key) { unset($this->items[$key]); } } Enumerable.php000064400000057461147536117460007367 0ustar00zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * * @param mixed ...$items * @return static */ public function zip($items); /** * Collect the values into a collection. * * @return \Illuminate\Support\Collection */ public function collect(); /** * Convert the collection to its string representation. * * @return string */ public function __toString(); /** * Add a method to the list of proxied methods. * * @param string $method * @return void */ public static function proxy($method); /** * Dynamically access collection proxies. * * @param string $key * @return mixed * * @throws \Exception */ public function __get($key); } HigherOrderCollectionProxy.php000064400000002600147536117460012551 0ustar00method = $method; $this->collection = $collection; } /** * Proxy accessing an attribute onto the collection items. * * @param string $key * @return mixed */ public function __get($key) { return $this->collection->{$this->method}(function ($value) use ($key) { return is_array($value) ? $value[$key] : $value->{$key}; }); } /** * Proxy a method call onto the collection items. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->collection->{$this->method}(function ($value) use ($method, $parameters) { return $value->{$method}(...$parameters); }); } } HigherOrderWhenProxy.php000064400000002433147536117460011363 0ustar00condition = $condition; $this->collection = $collection; } /** * Proxy accessing an attribute onto the collection. * * @param string $key * @return mixed */ public function __get($key) { return $this->condition ? $this->collection->{$key} : $this->collection; } /** * Proxy a method call onto the collection. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->condition ? $this->collection->{$method}(...$parameters) : $this->collection; } } ItemNotFoundException.php000064400000000166147536117460011530 0ustar00source = $source; } elseif (is_null($source)) { $this->source = static::empty(); } else { $this->source = $this->getArrayableItems($source); } } /** * Create a collection with the given range. * * @param int $from * @param int $to * @return static */ public static function range($from, $to) { return new static(function () use ($from, $to) { if ($from <= $to) { for (; $from <= $to; $from++) { yield $from; } } else { for (; $from >= $to; $from--) { yield $from; } } }); } /** * Get all items in the enumerable. * * @return array */ public function all() { if (is_array($this->source)) { return $this->source; } return iterator_to_array($this->getIterator()); } /** * Eager load all items into a new lazy collection backed by an array. * * @return static */ public function eager() { return new static($this->all()); } /** * Cache values as they're enumerated. * * @return static */ public function remember() { $iterator = $this->getIterator(); $iteratorIndex = 0; $cache = []; return new static(function () use ($iterator, &$iteratorIndex, &$cache) { for ($index = 0; true; $index++) { if (array_key_exists($index, $cache)) { yield $cache[$index][0] => $cache[$index][1]; continue; } if ($iteratorIndex < $index) { $iterator->next(); $iteratorIndex++; } if (! $iterator->valid()) { break; } $cache[$index] = [$iterator->key(), $iterator->current()]; yield $cache[$index][0] => $cache[$index][1]; } }); } /** * Get the average value of a given key. * * @param callable|string|null $callback * @return mixed */ public function avg($callback = null) { return $this->collect()->avg($callback); } /** * Get the median of a given key. * * @param string|array|null $key * @return mixed */ public function median($key = null) { return $this->collect()->median($key); } /** * Get the mode of a given key. * * @param string|array|null $key * @return array|null */ public function mode($key = null) { return $this->collect()->mode($key); } /** * Collapse the collection of items into a single array. * * @return static */ public function collapse() { return new static(function () { foreach ($this as $values) { if (is_array($values) || $values instanceof Enumerable) { foreach ($values as $value) { yield $value; } } } }); } /** * Determine if an item exists in the enumerable. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return bool */ public function contains($key, $operator = null, $value = null) { if (func_num_args() === 1 && $this->useAsCallable($key)) { $placeholder = new stdClass; return $this->first($key, $placeholder) !== $placeholder; } if (func_num_args() === 1) { $needle = $key; foreach ($this as $value) { if ($value == $needle) { return true; } } return false; } return $this->contains($this->operatorForWhere(...func_get_args())); } /** * Cross join the given iterables, returning all possible permutations. * * @param array ...$arrays * @return static */ public function crossJoin(...$arrays) { return $this->passthru('crossJoin', func_get_args()); } /** * Count the number of items in the collection by a field or using a callback. * * @param callable|string $countBy * @return static */ public function countBy($countBy = null) { $countBy = is_null($countBy) ? $this->identity() : $this->valueRetriever($countBy); return new static(function () use ($countBy) { $counts = []; foreach ($this as $key => $value) { $group = $countBy($value, $key); if (empty($counts[$group])) { $counts[$group] = 0; } $counts[$group]++; } yield from $counts; }); } /** * Get the items that are not present in the given items. * * @param mixed $items * @return static */ public function diff($items) { return $this->passthru('diff', func_get_args()); } /** * Get the items that are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffUsing($items, callable $callback) { return $this->passthru('diffUsing', func_get_args()); } /** * Get the items whose keys and values are not present in the given items. * * @param mixed $items * @return static */ public function diffAssoc($items) { return $this->passthru('diffAssoc', func_get_args()); } /** * Get the items whose keys and values are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffAssocUsing($items, callable $callback) { return $this->passthru('diffAssocUsing', func_get_args()); } /** * Get the items whose keys are not present in the given items. * * @param mixed $items * @return static */ public function diffKeys($items) { return $this->passthru('diffKeys', func_get_args()); } /** * Get the items whose keys are not present in the given items, using the callback. * * @param mixed $items * @param callable $callback * @return static */ public function diffKeysUsing($items, callable $callback) { return $this->passthru('diffKeysUsing', func_get_args()); } /** * Retrieve duplicate items. * * @param callable|string|null $callback * @param bool $strict * @return static */ public function duplicates($callback = null, $strict = false) { return $this->passthru('duplicates', func_get_args()); } /** * Retrieve duplicate items using strict comparison. * * @param callable|string|null $callback * @return static */ public function duplicatesStrict($callback = null) { return $this->passthru('duplicatesStrict', func_get_args()); } /** * Get all items except for those with the specified keys. * * @param mixed $keys * @return static */ public function except($keys) { return $this->passthru('except', func_get_args()); } /** * Run a filter over each of the items. * * @param callable|null $callback * @return static */ public function filter(callable $callback = null) { if (is_null($callback)) { $callback = function ($value) { return (bool) $value; }; } return new static(function () use ($callback) { foreach ($this as $key => $value) { if ($callback($value, $key)) { yield $key => $value; } } }); } /** * Get the first item from the enumerable passing the given truth test. * * @param callable|null $callback * @param mixed $default * @return mixed */ public function first(callable $callback = null, $default = null) { $iterator = $this->getIterator(); if (is_null($callback)) { if (! $iterator->valid()) { return value($default); } return $iterator->current(); } foreach ($iterator as $key => $value) { if ($callback($value, $key)) { return $value; } } return value($default); } /** * Get a flattened list of the items in the collection. * * @param int $depth * @return static */ public function flatten($depth = INF) { $instance = new static(function () use ($depth) { foreach ($this as $item) { if (! is_array($item) && ! $item instanceof Enumerable) { yield $item; } elseif ($depth === 1) { yield from $item; } else { yield from (new static($item))->flatten($depth - 1); } } }); return $instance->values(); } /** * Flip the items in the collection. * * @return static */ public function flip() { return new static(function () { foreach ($this as $key => $value) { yield $value => $key; } }); } /** * Get an item by key. * * @param mixed $key * @param mixed $default * @return mixed */ public function get($key, $default = null) { if (is_null($key)) { return; } foreach ($this as $outerKey => $outerValue) { if ($outerKey == $key) { return $outerValue; } } return value($default); } /** * Group an associative array by a field or using a callback. * * @param array|callable|string $groupBy * @param bool $preserveKeys * @return static */ public function groupBy($groupBy, $preserveKeys = false) { return $this->passthru('groupBy', func_get_args()); } /** * Key an associative array by a field or using a callback. * * @param callable|string $keyBy * @return static */ public function keyBy($keyBy) { return new static(function () use ($keyBy) { $keyBy = $this->valueRetriever($keyBy); foreach ($this as $key => $item) { $resolvedKey = $keyBy($item, $key); if (is_object($resolvedKey)) { $resolvedKey = (string) $resolvedKey; } yield $resolvedKey => $item; } }); } /** * Determine if an item exists in the collection by key. * * @param mixed $key * @return bool */ public function has($key) { $keys = array_flip(is_array($key) ? $key : func_get_args()); $count = count($keys); foreach ($this as $key => $value) { if (array_key_exists($key, $keys) && --$count == 0) { return true; } } return false; } /** * Determine if any of the keys exist in the collection. * * @param mixed $key * @return bool */ public function hasAny($key) { $keys = array_flip(is_array($key) ? $key : func_get_args()); foreach ($this as $key => $value) { if (array_key_exists($key, $keys)) { return true; } } return false; } /** * Concatenate values of a given key as a string. * * @param string $value * @param string|null $glue * @return string */ public function implode($value, $glue = null) { return $this->collect()->implode(...func_get_args()); } /** * Intersect the collection with the given items. * * @param mixed $items * @return static */ public function intersect($items) { return $this->passthru('intersect', func_get_args()); } /** * Intersect the collection with the given items by key. * * @param mixed $items * @return static */ public function intersectByKeys($items) { return $this->passthru('intersectByKeys', func_get_args()); } /** * Determine if the items are empty or not. * * @return bool */ public function isEmpty() { return ! $this->getIterator()->valid(); } /** * Determine if the collection contains a single item. * * @return bool */ public function containsOneItem() { return $this->take(2)->count() === 1; } /** * Join all items from the collection using a string. The final items can use a separate glue string. * * @param string $glue * @param string $finalGlue * @return string */ public function join($glue, $finalGlue = '') { return $this->collect()->join(...func_get_args()); } /** * Get the keys of the collection items. * * @return static */ public function keys() { return new static(function () { foreach ($this as $key => $value) { yield $key; } }); } /** * Get the last item from the collection. * * @param callable|null $callback * @param mixed $default * @return mixed */ public function last(callable $callback = null, $default = null) { $needle = $placeholder = new stdClass; foreach ($this as $key => $value) { if (is_null($callback) || $callback($value, $key)) { $needle = $value; } } return $needle === $placeholder ? value($default) : $needle; } /** * Get the values of a given key. * * @param string|array $value * @param string|null $key * @return static */ public function pluck($value, $key = null) { return new static(function () use ($value, $key) { [$value, $key] = $this->explodePluckParameters($value, $key); foreach ($this as $item) { $itemValue = data_get($item, $value); if (is_null($key)) { yield $itemValue; } else { $itemKey = data_get($item, $key); if (is_object($itemKey) && method_exists($itemKey, '__toString')) { $itemKey = (string) $itemKey; } yield $itemKey => $itemValue; } } }); } /** * Run a map over each of the items. * * @param callable $callback * @return static */ public function map(callable $callback) { return new static(function () use ($callback) { foreach ($this as $key => $value) { yield $key => $callback($value, $key); } }); } /** * Run a dictionary map over the items. * * The callback should return an associative array with a single key/value pair. * * @param callable $callback * @return static */ public function mapToDictionary(callable $callback) { return $this->passthru('mapToDictionary', func_get_args()); } /** * Run an associative map over each of the items. * * The callback should return an associative array with a single key/value pair. * * @param callable $callback * @return static */ public function mapWithKeys(callable $callback) { return new static(function () use ($callback) { foreach ($this as $key => $value) { yield from $callback($value, $key); } }); } /** * Merge the collection with the given items. * * @param mixed $items * @return static */ public function merge($items) { return $this->passthru('merge', func_get_args()); } /** * Recursively merge the collection with the given items. * * @param mixed $items * @return static */ public function mergeRecursive($items) { return $this->passthru('mergeRecursive', func_get_args()); } /** * Create a collection by using this collection for keys and another for its values. * * @param mixed $values * @return static */ public function combine($values) { return new static(function () use ($values) { $values = $this->makeIterator($values); $errorMessage = 'Both parameters should have an equal number of elements'; foreach ($this as $key) { if (! $values->valid()) { trigger_error($errorMessage, E_USER_WARNING); break; } yield $key => $values->current(); $values->next(); } if ($values->valid()) { trigger_error($errorMessage, E_USER_WARNING); } }); } /** * Union the collection with the given items. * * @param mixed $items * @return static */ public function union($items) { return $this->passthru('union', func_get_args()); } /** * Create a new collection consisting of every n-th element. * * @param int $step * @param int $offset * @return static */ public function nth($step, $offset = 0) { return new static(function () use ($step, $offset) { $position = 0; foreach ($this as $item) { if ($position % $step === $offset) { yield $item; } $position++; } }); } /** * Get the items with the specified keys. * * @param mixed $keys * @return static */ public function only($keys) { if ($keys instanceof Enumerable) { $keys = $keys->all(); } elseif (! is_null($keys)) { $keys = is_array($keys) ? $keys : func_get_args(); } return new static(function () use ($keys) { if (is_null($keys)) { yield from $this; } else { $keys = array_flip($keys); foreach ($this as $key => $value) { if (array_key_exists($key, $keys)) { yield $key => $value; unset($keys[$key]); if (empty($keys)) { break; } } } } }); } /** * Push all of the given items onto the collection. * * @param iterable $source * @return static */ public function concat($source) { return (new static(function () use ($source) { yield from $this; yield from $source; }))->values(); } /** * Get one or a specified number of items randomly from the collection. * * @param int|null $number * @return static|mixed * * @throws \InvalidArgumentException */ public function random($number = null) { $result = $this->collect()->random(...func_get_args()); return is_null($number) ? $result : new static($result); } /** * Replace the collection items with the given items. * * @param mixed $items * @return static */ public function replace($items) { return new static(function () use ($items) { $items = $this->getArrayableItems($items); foreach ($this as $key => $value) { if (array_key_exists($key, $items)) { yield $key => $items[$key]; unset($items[$key]); } else { yield $key => $value; } } foreach ($items as $key => $value) { yield $key => $value; } }); } /** * Recursively replace the collection items with the given items. * * @param mixed $items * @return static */ public function replaceRecursive($items) { return $this->passthru('replaceRecursive', func_get_args()); } /** * Reverse items order. * * @return static */ public function reverse() { return $this->passthru('reverse', func_get_args()); } /** * Search the collection for a given value and return the corresponding key if successful. * * @param mixed $value * @param bool $strict * @return mixed */ public function search($value, $strict = false) { $predicate = $this->useAsCallable($value) ? $value : function ($item) use ($value, $strict) { return $strict ? $item === $value : $item == $value; }; foreach ($this as $key => $item) { if ($predicate($item, $key)) { return $key; } } return false; } /** * Shuffle the items in the collection. * * @param int|null $seed * @return static */ public function shuffle($seed = null) { return $this->passthru('shuffle', func_get_args()); } /** * Create chunks representing a "sliding window" view of the items in the collection. * * @param int $size * @param int $step * @return static */ public function sliding($size = 2, $step = 1) { return new static(function () use ($size, $step) { $iterator = $this->getIterator(); $chunk = []; while ($iterator->valid()) { $chunk[$iterator->key()] = $iterator->current(); if (count($chunk) == $size) { yield tap(new static($chunk), function () use (&$chunk, $step) { $chunk = array_slice($chunk, $step, null, true); }); // If the $step between chunks is bigger than each chunk's $size // we will skip the extra items (which should never be in any // chunk) before we continue to the next chunk in the loop. if ($step > $size) { $skip = $step - $size; for ($i = 0; $i < $skip && $iterator->valid(); $i++) { $iterator->next(); } } } $iterator->next(); } }); } /** * Skip the first {$count} items. * * @param int $count * @return static */ public function skip($count) { return new static(function () use ($count) { $iterator = $this->getIterator(); while ($iterator->valid() && $count--) { $iterator->next(); } while ($iterator->valid()) { yield $iterator->key() => $iterator->current(); $iterator->next(); } }); } /** * Skip items in the collection until the given condition is met. * * @param mixed $value * @return static */ public function skipUntil($value) { $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return $this->skipWhile($this->negate($callback)); } /** * Skip items in the collection while the given condition is met. * * @param mixed $value * @return static */ public function skipWhile($value) { $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return new static(function () use ($callback) { $iterator = $this->getIterator(); while ($iterator->valid() && $callback($iterator->current(), $iterator->key())) { $iterator->next(); } while ($iterator->valid()) { yield $iterator->key() => $iterator->current(); $iterator->next(); } }); } /** * Get a slice of items from the enumerable. * * @param int $offset * @param int|null $length * @return static */ public function slice($offset, $length = null) { if ($offset < 0 || $length < 0) { return $this->passthru('slice', func_get_args()); } $instance = $this->skip($offset); return is_null($length) ? $instance : $instance->take($length); } /** * Split a collection into a certain number of groups. * * @param int $numberOfGroups * @return static */ public function split($numberOfGroups) { return $this->passthru('split', func_get_args()); } /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return mixed * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException */ public function sole($key = null, $operator = null, $value = null) { $filter = func_num_args() > 1 ? $this->operatorForWhere(...func_get_args()) : $key; return $this ->when($filter) ->filter($filter) ->take(2) ->collect() ->sole(); } /** * Get the first item in the collection but throw an exception if no matching items exist. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return mixed * * @throws \Illuminate\Support\ItemNotFoundException */ public function firstOrFail($key = null, $operator = null, $value = null) { $filter = func_num_args() > 1 ? $this->operatorForWhere(...func_get_args()) : $key; return $this ->when($filter) ->filter($filter) ->take(1) ->collect() ->firstOrFail(); } /** * Chunk the collection into chunks of the given size. * * @param int $size * @return static */ public function chunk($size) { if ($size <= 0) { return static::empty(); } return new static(function () use ($size) { $iterator = $this->getIterator(); while ($iterator->valid()) { $chunk = []; while (true) { $chunk[$iterator->key()] = $iterator->current(); if (count($chunk) < $size) { $iterator->next(); if (! $iterator->valid()) { break; } } else { break; } } yield new static($chunk); $iterator->next(); } }); } /** * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups * @return static */ public function splitIn($numberOfGroups) { return $this->chunk(ceil($this->count() / $numberOfGroups)); } /** * Chunk the collection into chunks with a callback. * * @param callable $callback * @return static */ public function chunkWhile(callable $callback) { return new static(function () use ($callback) { $iterator = $this->getIterator(); $chunk = new Collection; if ($iterator->valid()) { $chunk[$iterator->key()] = $iterator->current(); $iterator->next(); } while ($iterator->valid()) { if (! $callback($iterator->current(), $iterator->key(), $chunk)) { yield new static($chunk); $chunk = new Collection; } $chunk[$iterator->key()] = $iterator->current(); $iterator->next(); } if ($chunk->isNotEmpty()) { yield new static($chunk); } }); } /** * Sort through each item with a callback. * * @param callable|null|int $callback * @return static */ public function sort($callback = null) { return $this->passthru('sort', func_get_args()); } /** * Sort items in descending order. * * @param int $options * @return static */ public function sortDesc($options = SORT_REGULAR) { return $this->passthru('sortDesc', func_get_args()); } /** * Sort the collection using the given callback. * * @param callable|string $callback * @param int $options * @param bool $descending * @return static */ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) { return $this->passthru('sortBy', func_get_args()); } /** * Sort the collection in descending order using the given callback. * * @param callable|string $callback * @param int $options * @return static */ public function sortByDesc($callback, $options = SORT_REGULAR) { return $this->passthru('sortByDesc', func_get_args()); } /** * Sort the collection keys. * * @param int $options * @param bool $descending * @return static */ public function sortKeys($options = SORT_REGULAR, $descending = false) { return $this->passthru('sortKeys', func_get_args()); } /** * Sort the collection keys in descending order. * * @param int $options * @return static */ public function sortKeysDesc($options = SORT_REGULAR) { return $this->passthru('sortKeysDesc', func_get_args()); } /** * Take the first or last {$limit} items. * * @param int $limit * @return static */ public function take($limit) { if ($limit < 0) { return $this->passthru('take', func_get_args()); } return new static(function () use ($limit) { $iterator = $this->getIterator(); while ($limit--) { if (! $iterator->valid()) { break; } yield $iterator->key() => $iterator->current(); if ($limit) { $iterator->next(); } } }); } /** * Take items in the collection until the given condition is met. * * @param mixed $value * @return static */ public function takeUntil($value) { $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return new static(function () use ($callback) { foreach ($this as $key => $item) { if ($callback($item, $key)) { break; } yield $key => $item; } }); } /** * Take items in the collection until a given point in time. * * @param \DateTimeInterface $timeout * @return static */ public function takeUntilTimeout(DateTimeInterface $timeout) { $timeout = $timeout->getTimestamp(); return $this->takeWhile(function () use ($timeout) { return $this->now() < $timeout; }); } /** * Take items in the collection while the given condition is met. * * @param mixed $value * @return static */ public function takeWhile($value) { $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return $this->takeUntil(function ($item, $key) use ($callback) { return ! $callback($item, $key); }); } /** * Pass each item in the collection to the given callback, lazily. * * @param callable $callback * @return static */ public function tapEach(callable $callback) { return new static(function () use ($callback) { foreach ($this as $key => $value) { $callback($value, $key); yield $key => $value; } }); } /** * Return only unique items from the collection array. * * @param string|callable|null $key * @param bool $strict * @return static */ public function unique($key = null, $strict = false) { $callback = $this->valueRetriever($key); return new static(function () use ($callback, $strict) { $exists = []; foreach ($this as $key => $item) { if (! in_array($id = $callback($item, $key), $exists, $strict)) { yield $key => $item; $exists[] = $id; } } }); } /** * Reset the keys on the underlying array. * * @return static */ public function values() { return new static(function () { foreach ($this as $item) { yield $item; } }); } /** * Zip the collection together with one or more arrays. * * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * * @param mixed ...$items * @return static */ public function zip($items) { $iterables = func_get_args(); return new static(function () use ($iterables) { $iterators = Collection::make($iterables)->map(function ($iterable) { return $this->makeIterator($iterable); })->prepend($this->getIterator()); while ($iterators->contains->valid()) { yield new static($iterators->map->current()); $iterators->each->next(); } }); } /** * Pad collection to the specified length with a value. * * @param int $size * @param mixed $value * @return static */ public function pad($size, $value) { if ($size < 0) { return $this->passthru('pad', func_get_args()); } return new static(function () use ($size, $value) { $yielded = 0; foreach ($this as $index => $item) { yield $index => $item; $yielded++; } while ($yielded++ < $size) { yield $value; } }); } /** * Get the values iterator. * * @return \Traversable */ #[\ReturnTypeWillChange] public function getIterator() { return $this->makeIterator($this->source); } /** * Count the number of items in the collection. * * @return int */ #[\ReturnTypeWillChange] public function count() { if (is_array($this->source)) { return count($this->source); } return iterator_count($this->getIterator()); } /** * Make an iterator from the given source. * * @param mixed $source * @return \Traversable */ protected function makeIterator($source) { if ($source instanceof IteratorAggregate) { return $source->getIterator(); } if (is_array($source)) { return new ArrayIterator($source); } return $source(); } /** * Explode the "value" and "key" arguments passed to "pluck". * * @param string|array $value * @param string|array|null $key * @return array */ protected function explodePluckParameters($value, $key) { $value = is_string($value) ? explode('.', $value) : $value; $key = is_null($key) || is_array($key) ? $key : explode('.', $key); return [$value, $key]; } /** * Pass this lazy collection through a method on the collection class. * * @param string $method * @param array $params * @return static */ protected function passthru($method, array $params) { return new static(function () use ($method, $params) { yield from $this->collect()->$method(...$params); }); } /** * Get the current time. * * @return int */ protected function now() { return time(); } } MultipleItemsFoundException.php000064400000000174147536117460012745 0ustar00all() : $value; } /** * Create a new instance with no items. * * @return static */ public static function empty() { return new static([]); } /** * Create a new collection by invoking the callback a given amount of times. * * @param int $number * @param callable|null $callback * @return static */ public static function times($number, callable $callback = null) { if ($number < 1) { return new static; } return static::range(1, $number) ->when($callback) ->map($callback); } /** * Alias for the "avg" method. * * @param callable|string|null $callback * @return mixed */ public function average($callback = null) { return $this->avg($callback); } /** * Alias for the "contains" method. * * @param mixed $key * @param mixed $operator * @param mixed $value * @return bool */ public function some($key, $operator = null, $value = null) { return $this->contains(...func_get_args()); } /** * Determine if an item exists, using strict comparison. * * @param mixed $key * @param mixed $value * @return bool */ public function containsStrict($key, $value = null) { if (func_num_args() === 2) { return $this->contains(function ($item) use ($key, $value) { return data_get($item, $key) === $value; }); } if ($this->useAsCallable($key)) { return ! is_null($this->first($key)); } foreach ($this as $item) { if ($item === $key) { return true; } } return false; } /** * Dump the items and end the script. * * @param mixed ...$args * @return void */ public function dd(...$args) { $this->dump(...$args); exit(1); } /** * Dump the items. * * @return $this */ public function dump() { (new Collection(func_get_args())) ->push($this->all()) ->each(function ($item) { VarDumper::dump($item); }); return $this; } /** * Execute a callback over each item. * * @param callable $callback * @return $this */ public function each(callable $callback) { foreach ($this as $key => $item) { if ($callback($item, $key) === false) { break; } } return $this; } /** * Execute a callback over each nested chunk of items. * * @param callable $callback * @return static */ public function eachSpread(callable $callback) { return $this->each(function ($chunk, $key) use ($callback) { $chunk[] = $key; return $callback(...$chunk); }); } /** * Determine if all items pass the given truth test. * * @param string|callable $key * @param mixed $operator * @param mixed $value * @return bool */ public function every($key, $operator = null, $value = null) { if (func_num_args() === 1) { $callback = $this->valueRetriever($key); foreach ($this as $k => $v) { if (! $callback($v, $k)) { return false; } } return true; } return $this->every($this->operatorForWhere(...func_get_args())); } /** * Get the first item by the given key value pair. * * @param string $key * @param mixed $operator * @param mixed $value * @return mixed */ public function firstWhere($key, $operator = null, $value = null) { return $this->first($this->operatorForWhere(...func_get_args())); } /** * Determine if the collection is not empty. * * @return bool */ public function isNotEmpty() { return ! $this->isEmpty(); } /** * Run a map over each nested chunk of items. * * @param callable $callback * @return static */ public function mapSpread(callable $callback) { return $this->map(function ($chunk, $key) use ($callback) { $chunk[] = $key; return $callback(...$chunk); }); } /** * Run a grouping map over the items. * * The callback should return an associative array with a single key/value pair. * * @param callable $callback * @return static */ public function mapToGroups(callable $callback) { $groups = $this->mapToDictionary($callback); return $groups->map([$this, 'make']); } /** * Map a collection and flatten the result by a single level. * * @param callable $callback * @return static */ public function flatMap(callable $callback) { return $this->map($callback)->collapse(); } /** * Map the values into a new class. * * @param string $class * @return static */ public function mapInto($class) { return $this->map(function ($value, $key) use ($class) { return new $class($value, $key); }); } /** * Get the min value of a given key. * * @param callable|string|null $callback * @return mixed */ public function min($callback = null) { $callback = $this->valueRetriever($callback); return $this->map(function ($value) use ($callback) { return $callback($value); })->filter(function ($value) { return ! is_null($value); })->reduce(function ($result, $value) { return is_null($result) || $value < $result ? $value : $result; }); } /** * Get the max value of a given key. * * @param callable|string|null $callback * @return mixed */ public function max($callback = null) { $callback = $this->valueRetriever($callback); return $this->filter(function ($value) { return ! is_null($value); })->reduce(function ($result, $item) use ($callback) { $value = $callback($item); return is_null($result) || $value > $result ? $value : $result; }); } /** * "Paginate" the collection by slicing it into a smaller collection. * * @param int $page * @param int $perPage * @return static */ public function forPage($page, $perPage) { $offset = max(0, ($page - 1) * $perPage); return $this->slice($offset, $perPage); } /** * Partition the collection into two arrays using the given callback or key. * * @param callable|string $key * @param mixed $operator * @param mixed $value * @return static */ public function partition($key, $operator = null, $value = null) { $passed = []; $failed = []; $callback = func_num_args() === 1 ? $this->valueRetriever($key) : $this->operatorForWhere(...func_get_args()); foreach ($this as $key => $item) { if ($callback($item, $key)) { $passed[$key] = $item; } else { $failed[$key] = $item; } } return new static([new static($passed), new static($failed)]); } /** * Get the sum of the given values. * * @param callable|string|null $callback * @return mixed */ public function sum($callback = null) { $callback = is_null($callback) ? $this->identity() : $this->valueRetriever($callback); return $this->reduce(function ($result, $item) use ($callback) { return $result + $callback($item); }, 0); } /** * Apply the callback if the value is truthy. * * @param bool|mixed $value * @param callable|null $callback * @param callable|null $default * @return static|mixed */ public function when($value, callable $callback = null, callable $default = null) { if (! $callback) { return new HigherOrderWhenProxy($this, $value); } if ($value) { return $callback($this, $value); } elseif ($default) { return $default($this, $value); } return $this; } /** * Apply the callback if the collection is empty. * * @param callable $callback * @param callable|null $default * @return static|mixed */ public function whenEmpty(callable $callback, callable $default = null) { return $this->when($this->isEmpty(), $callback, $default); } /** * Apply the callback if the collection is not empty. * * @param callable $callback * @param callable|null $default * @return static|mixed */ public function whenNotEmpty(callable $callback, callable $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } /** * Apply the callback if the value is falsy. * * @param bool $value * @param callable $callback * @param callable|null $default * @return static|mixed */ public function unless($value, callable $callback, callable $default = null) { return $this->when(! $value, $callback, $default); } /** * Apply the callback unless the collection is empty. * * @param callable $callback * @param callable|null $default * @return static|mixed */ public function unlessEmpty(callable $callback, callable $default = null) { return $this->whenNotEmpty($callback, $default); } /** * Apply the callback unless the collection is not empty. * * @param callable $callback * @param callable|null $default * @return static|mixed */ public function unlessNotEmpty(callable $callback, callable $default = null) { return $this->whenEmpty($callback, $default); } /** * Filter items by the given key value pair. * * @param string $key * @param mixed $operator * @param mixed $value * @return static */ public function where($key, $operator = null, $value = null) { return $this->filter($this->operatorForWhere(...func_get_args())); } /** * Filter items where the value for the given key is null. * * @param string|null $key * @return static */ public function whereNull($key = null) { return $this->whereStrict($key, null); } /** * Filter items where the value for the given key is not null. * * @param string|null $key * @return static */ public function whereNotNull($key = null) { return $this->where($key, '!==', null); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key * @param mixed $value * @return static */ public function whereStrict($key, $value) { return $this->where($key, '===', $value); } /** * Filter items by the given key value pair. * * @param string $key * @param mixed $values * @param bool $strict * @return static */ public function whereIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); return $this->filter(function ($item) use ($key, $values, $strict) { return in_array(data_get($item, $key), $values, $strict); }); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key * @param mixed $values * @return static */ public function whereInStrict($key, $values) { return $this->whereIn($key, $values, true); } /** * Filter items such that the value of the given key is between the given values. * * @param string $key * @param array $values * @return static */ public function whereBetween($key, $values) { return $this->where($key, '>=', reset($values))->where($key, '<=', end($values)); } /** * Filter items such that the value of the given key is not between the given values. * * @param string $key * @param array $values * @return static */ public function whereNotBetween($key, $values) { return $this->filter(function ($item) use ($key, $values) { return data_get($item, $key) < reset($values) || data_get($item, $key) > end($values); }); } /** * Filter items by the given key value pair. * * @param string $key * @param mixed $values * @param bool $strict * @return static */ public function whereNotIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); return $this->reject(function ($item) use ($key, $values, $strict) { return in_array(data_get($item, $key), $values, $strict); }); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key * @param mixed $values * @return static */ public function whereNotInStrict($key, $values) { return $this->whereNotIn($key, $values, true); } /** * Filter the items, removing any items that don't match the given type(s). * * @param string|string[] $type * @return static */ public function whereInstanceOf($type) { return $this->filter(function ($value) use ($type) { if (is_array($type)) { foreach ($type as $classType) { if ($value instanceof $classType) { return true; } } return false; } return $value instanceof $type; }); } /** * Pass the collection to the given callback and return the result. * * @param callable $callback * @return mixed */ public function pipe(callable $callback) { return $callback($this); } /** * Pass the collection into a new class. * * @param string $class * @return mixed */ public function pipeInto($class) { return new $class($this); } /** * Pass the collection to the given callback and then return it. * * @param callable $callback * @return $this */ public function tap(callable $callback) { $callback(clone $this); return $this; } /** * Reduce the collection to a single value. * * @param callable $callback * @param mixed $initial * @return mixed */ public function reduce(callable $callback, $initial = null) { $result = $initial; foreach ($this as $key => $value) { $result = $callback($result, $value, $key); } return $result; } /** * Reduce the collection to multiple aggregate values. * * @param callable $callback * @param mixed ...$initial * @return array * * @deprecated Use "reduceSpread" instead * * @throws \UnexpectedValueException */ public function reduceMany(callable $callback, ...$initial) { return $this->reduceSpread($callback, ...$initial); } /** * Reduce the collection to multiple aggregate values. * * @param callable $callback * @param mixed ...$initial * @return array * * @throws \UnexpectedValueException */ public function reduceSpread(callable $callback, ...$initial) { $result = $initial; foreach ($this as $key => $value) { $result = call_user_func_array($callback, array_merge($result, [$value, $key])); if (! is_array($result)) { throw new UnexpectedValueException(sprintf( "%s::reduceMany expects reducer to return an array, but got a '%s' instead.", class_basename(static::class), gettype($result) )); } } return $result; } /** * Reduce an associative collection to a single value. * * @param callable $callback * @param mixed $initial * @return mixed */ public function reduceWithKeys(callable $callback, $initial = null) { return $this->reduce($callback, $initial); } /** * Create a collection of all elements that do not pass a given truth test. * * @param callable|mixed $callback * @return static */ public function reject($callback = true) { $useAsCallable = $this->useAsCallable($callback); return $this->filter(function ($value, $key) use ($callback, $useAsCallable) { return $useAsCallable ? ! $callback($value, $key) : $value != $callback; }); } /** * Return only unique items from the collection array using strict comparison. * * @param string|callable|null $key * @return static */ public function uniqueStrict($key = null) { return $this->unique($key, true); } /** * Collect the values into a collection. * * @return \Illuminate\Support\Collection */ public function collect() { return new Collection($this->all()); } /** * Get the collection of items as a plain array. * * @return array */ public function toArray() { return $this->map(function ($value) { return $value instanceof Arrayable ? $value->toArray() : $value; })->all(); } /** * Convert the object into something JSON serializable. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return array_map(function ($value) { if ($value instanceof JsonSerializable) { return $value->jsonSerialize(); } elseif ($value instanceof Jsonable) { return json_decode($value->toJson(), true); } elseif ($value instanceof Arrayable) { return $value->toArray(); } return $value; }, $this->all()); } /** * Get the collection of items as JSON. * * @param int $options * @return string */ public function toJson($options = 0) { return json_encode($this->jsonSerialize(), $options); } /** * Get a CachingIterator instance. * * @param int $flags * @return \CachingIterator */ public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING) { return new CachingIterator($this->getIterator(), $flags); } /** * Convert the collection to its string representation. * * @return string */ public function __toString() { return $this->toJson(); } /** * Add a method to the list of proxied methods. * * @param string $method * @return void */ public static function proxy($method) { static::$proxies[] = $method; } /** * Dynamically access collection proxies. * * @param string $key * @return mixed * * @throws \Exception */ public function __get($key) { if (! in_array($key, static::$proxies)) { throw new Exception("Property [{$key}] does not exist on this collection instance."); } return new HigherOrderCollectionProxy($this, $key); } /** * Results array of items from Collection or Arrayable. * * @param mixed $items * @return array */ protected function getArrayableItems($items) { if (is_array($items)) { return $items; } elseif ($items instanceof Enumerable) { return $items->all(); } elseif ($items instanceof Arrayable) { return $items->toArray(); } elseif ($items instanceof Jsonable) { return json_decode($items->toJson(), true); } elseif ($items instanceof JsonSerializable) { return (array) $items->jsonSerialize(); } elseif ($items instanceof Traversable) { return iterator_to_array($items); } return (array) $items; } /** * Get an operator checker callback. * * @param string $key * @param string|null $operator * @param mixed $value * @return \Closure */ protected function operatorForWhere($key, $operator = null, $value = null) { if (func_num_args() === 1) { $value = true; $operator = '='; } if (func_num_args() === 2) { $value = $operator; $operator = '='; } return function ($item) use ($key, $operator, $value) { $retrieved = data_get($item, $key); $strings = array_filter([$retrieved, $value], function ($value) { return is_string($value) || (is_object($value) && method_exists($value, '__toString')); }); if (count($strings) < 2 && count(array_filter([$retrieved, $value], 'is_object')) == 1) { return in_array($operator, ['!=', '<>', '!==']); } switch ($operator) { default: case '=': case '==': return $retrieved == $value; case '!=': case '<>': return $retrieved != $value; case '<': return $retrieved < $value; case '>': return $retrieved > $value; case '<=': return $retrieved <= $value; case '>=': return $retrieved >= $value; case '===': return $retrieved === $value; case '!==': return $retrieved !== $value; } }; } /** * 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); } /** * Get a value retrieving callback. * * @param callable|string|null $value * @return callable */ protected function valueRetriever($value) { if ($this->useAsCallable($value)) { return $value; } return function ($item) use ($value) { return data_get($item, $value); }; } /** * Make a function to check an item's equality. * * @param mixed $value * @return \Closure */ protected function equality($value) { return function ($item) use ($value) { return $item === $value; }; } /** * Make a function using another function, by negating its result. * * @param \Closure $callback * @return \Closure */ protected function negate(Closure $callback) { return function (...$params) use ($callback) { return ! $callback(...$params); }; } /** * Make a function that returns what's passed to it. * * @return \Closure */ protected function identity() { return function ($value) { return $value; }; } } composer.json000064400000001733147536117460007310 0ustar00{ "name": "illuminate/collections", "description": "The Illuminate Collections package.", "license": "MIT", "homepage": "https://laravel.com", "support": { "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.3|^8.0", "illuminate/contracts": "^8.0", "illuminate/macroable": "^8.0" }, "autoload": { "psr-4": { "Illuminate\\Support\\": "" }, "files": [ "helpers.php" ] }, "extra": { "branch-alias": { "dev-master": "8.x-dev" } }, "suggest": { "symfony/var-dumper": "Required to use the dump method (^5.1.4)." }, "config": { "sort-packages": true }, "minimum-stability": "dev" } helpers.php000064400000011321147536117460006733 0ustar00 $segment) { unset($key[$i]); if (is_null($segment)) { return $target; } if ($segment === '*') { if ($target instanceof Collection) { $target = $target->all(); } elseif (! is_array($target)) { return value($default); } $result = []; foreach ($target as $item) { $result[] = data_get($item, $key); } return in_array('*', $key) ? Arr::collapse($result) : $result; } if (Arr::accessible($target) && Arr::exists($target, $segment)) { $target = $target[$segment]; } elseif (is_object($target) && isset($target->{$segment})) { $target = $target->{$segment}; } else { return value($default); } } return $target; } } if (! function_exists('data_set')) { /** * Set an item on an array or object using dot notation. * * @param mixed $target * @param string|array $key * @param mixed $value * @param bool $overwrite * @return mixed */ function data_set(&$target, $key, $value, $overwrite = true) { $segments = is_array($key) ? $key : explode('.', $key); if (($segment = array_shift($segments)) === '*') { if (! Arr::accessible($target)) { $target = []; } if ($segments) { foreach ($target as &$inner) { data_set($inner, $segments, $value, $overwrite); } } elseif ($overwrite) { foreach ($target as &$inner) { $inner = $value; } } } elseif (Arr::accessible($target)) { if ($segments) { if (! Arr::exists($target, $segment)) { $target[$segment] = []; } data_set($target[$segment], $segments, $value, $overwrite); } elseif ($overwrite || ! Arr::exists($target, $segment)) { $target[$segment] = $value; } } elseif (is_object($target)) { if ($segments) { if (! isset($target->{$segment})) { $target->{$segment} = []; } data_set($target->{$segment}, $segments, $value, $overwrite); } elseif ($overwrite || ! isset($target->{$segment})) { $target->{$segment} = $value; } } else { $target = []; if ($segments) { data_set($target[$segment], $segments, $value, $overwrite); } elseif ($overwrite) { $target[$segment] = $value; } } return $target; } } if (! function_exists('head')) { /** * Get the first element of an array. Useful for method chaining. * * @param array $array * @return mixed */ function head($array) { return reset($array); } } if (! function_exists('last')) { /** * Get the last element from an array. * * @param array $array * @return mixed */ function last($array) { return end($array); } } if (! function_exists('value')) { /** * Return the default value of the given value. * * @param mixed $value * @return mixed */ function value($value, ...$args) { return $value instanceof Closure ? $value(...$args) : $value; } }