Created
June 11, 2015 04:05
-
-
Save ethaizone/f022c359340d68d2a6f1 to your computer and use it in GitHub Desktop.
Array collection helpers. Ported from Laravel4.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Array collection helpers | |
* | |
* Ported from Laravel4. | |
* By EThaiZone | |
*/ | |
if ( ! function_exists('array_add')) | |
{ | |
/** | |
* Add an element to an array using "dot" notation if it doesn't exist. | |
* | |
* @param array $array | |
* @param string $key | |
* @param mixed $value | |
* @return array | |
*/ | |
function array_add($array, $key, $value) | |
{ | |
if (is_null(array_get($array, $key))) | |
{ | |
array_set($array, $key, $value); | |
} | |
return $array; | |
} | |
} | |
if ( ! function_exists('array_build')) | |
{ | |
/** | |
* Build a new array using a callback. | |
* | |
* @param array $array | |
* @param callable $callback | |
* @return array | |
*/ | |
function array_build($array, callable $callback) | |
{ | |
$results = []; | |
foreach ($array as $key => $value) | |
{ | |
list($innerKey, $innerValue) = call_user_func($callback, $key, $value); | |
$results[$innerKey] = $innerValue; | |
} | |
return $results; | |
} | |
} | |
if ( ! function_exists('array_collapse')) | |
{ | |
/** | |
* Collapse an array of arrays into a single array. | |
* | |
* @param array $array | |
* @return array | |
*/ | |
function array_collapse($array) | |
{ | |
$results = []; | |
foreach ($array as $values) | |
{ | |
$results = array_merge($results, $values); | |
} | |
return $results; | |
} | |
} | |
if ( ! function_exists('array_divide')) | |
{ | |
/** | |
* Divide an array into two arrays. One with keys and the other with values. | |
* | |
* @param array $array | |
* @return array | |
*/ | |
function array_divide($array) | |
{ | |
return [array_keys($array), array_values($array)]; | |
} | |
} | |
if ( ! function_exists('array_dot')) | |
{ | |
/** | |
* Flatten a multi-dimensional associative array with dots. | |
* | |
* @param array $array | |
* @param string $prepend | |
* @return array | |
*/ | |
function array_dot($array, $prepend = '') | |
{ | |
$results = []; | |
foreach ($array as $key => $value) | |
{ | |
if (is_array($value)) | |
{ | |
$recursiveResults = call_user_func_array(__FUNCTION__, [$value, $prepend.$key.'.']); | |
$results = array_merge($results, $recursiveResults); | |
} | |
else | |
{ | |
$results[$prepend.$key] = $value; | |
} | |
} | |
return $results; | |
} | |
} | |
if ( ! function_exists('array_except')) | |
{ | |
/** | |
* Get all of the given array except for a specified array of items. | |
* | |
* @param array $array | |
* @param array|string $keys | |
* @return array | |
*/ | |
function array_except($array, $keys) | |
{ | |
array_forget($array, $keys); | |
return $array; | |
} | |
} | |
if ( ! function_exists('array_fetch')) | |
{ | |
/** | |
* Fetch a flattened array of a nested array element. | |
* | |
* @param array $array | |
* @param string $key | |
* @return array | |
*/ | |
function array_fetch($array, $key) | |
{ | |
foreach (explode('.', $key) as $segment) | |
{ | |
$results = []; | |
foreach ($array as $value) | |
{ | |
if (array_key_exists($segment, $value = (array) $value)) | |
{ | |
$results[] = $value[$segment]; | |
} | |
} | |
$array = array_values($results); | |
} | |
return array_values($results); | |
} | |
} | |
if ( ! function_exists('array_first')) | |
{ | |
/** | |
* Return the first element in an array passing a given truth test. | |
* | |
* @param array $array | |
* @param callable $callback | |
* @param mixed $default | |
* @return mixed | |
*/ | |
function array_first($array, callable $callback, $default = null) | |
{ | |
foreach ($array as $key => $value) | |
{ | |
if (call_user_func($callback, $key, $value)) return $value; | |
} | |
return value($default); | |
} | |
} | |
if ( ! function_exists('array_last')) | |
{ | |
/** | |
* Return the last element in an array passing a given truth test. | |
* | |
* @param array $array | |
* @param callable $callback | |
* @param mixed $default | |
* @return mixed | |
*/ | |
function array_last($array, $callback, $default = null) | |
{ | |
return array_first(array_reverse($array), $callback, $default); | |
} | |
} | |
if ( ! function_exists('array_flatten')) | |
{ | |
/** | |
* Flatten a multi-dimensional array into a single level. | |
* | |
* @param array $array | |
* @return array | |
*/ | |
function array_flatten($array) | |
{ | |
$return = []; | |
array_walk_recursive($array, function($x) use (&$return) { $return[] = $x; }); | |
return $return; | |
} | |
} | |
if ( ! function_exists('array_forget')) | |
{ | |
/** | |
* Remove one or many array items from a given array using "dot" notation. | |
* | |
* @param array $array | |
* @param array|string $keys | |
* @return void | |
*/ | |
function array_forget(&$array, $keys) | |
{ | |
$original =& $array; | |
foreach ((array) $keys as $key) | |
{ | |
$parts = explode('.', $key); | |
while (count($parts) > 1) | |
{ | |
$part = array_shift($parts); | |
if (isset($array[$part]) && is_array($array[$part])) | |
{ | |
$array =& $array[$part]; | |
} | |
} | |
unset($array[array_shift($parts)]); | |
// clean up after each pass | |
$array =& $original; | |
} | |
} | |
} | |
if ( ! function_exists('array_get')) | |
{ | |
/** | |
* Get an item from an array using "dot" notation. | |
* | |
* @param array $array | |
* @param string $key | |
* @param mixed $default | |
* @return mixed | |
*/ | |
function array_get($array, $key, $default = null) | |
{ | |
if (is_null($key)) return $array; | |
if (isset($array[$key])) return $array[$key]; | |
foreach (explode('.', $key) as $segment) | |
{ | |
if ( ! is_array($array) || ! array_key_exists($segment, $array)) | |
{ | |
return value($default); | |
} | |
$array = $array[$segment]; | |
} | |
return $array; | |
} | |
} | |
if ( ! function_exists('array_has')) | |
{ | |
/** | |
* Check if an item exists in an array using "dot" notation. | |
* | |
* @param array $array | |
* @param string $key | |
* @return bool | |
*/ | |
function array_has($array, $key) | |
{ | |
if (empty($array) || is_null($key)) return false; | |
if (array_key_exists($key, $array)) return true; | |
foreach (explode('.', $key) as $segment) | |
{ | |
if ( ! is_array($array) || ! array_key_exists($segment, $array)) | |
{ | |
return false; | |
} | |
$array = $array[$segment]; | |
} | |
return true; | |
} | |
} | |
if ( ! function_exists('array_only')) | |
{ | |
/** | |
* Get a subset of the items from the given array. | |
* | |
* @param array $array | |
* @param array|string $keys | |
* @return array | |
*/ | |
function array_only($array, $keys) | |
{ | |
return array_intersect_key($array, array_flip((array) $keys)); | |
} | |
} | |
if ( ! function_exists('array_pluck')) | |
{ | |
/** | |
* Pluck an array of values from an array. | |
* | |
* @param array $array | |
* @param string $value | |
* @param string $key | |
* @return array | |
*/ | |
function array_pluck($array, $value, $key = null) | |
{ | |
$results = []; | |
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); | |
$results[$itemKey] = $itemValue; | |
} | |
} | |
return $results; | |
} | |
} | |
if ( ! function_exists('array_pull')) | |
{ | |
/** | |
* Get a value from the array, and remove it. | |
* | |
* @param array $array | |
* @param string $key | |
* @param mixed $default | |
* @return mixed | |
*/ | |
function array_pull(&$array, $key, $default = null) | |
{ | |
$value = array_get($array, $key, $default); | |
array_forget($array, $key); | |
return $value; | |
} | |
} | |
if ( ! function_exists('array_set')) | |
{ | |
/** | |
* 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 $key | |
* @param mixed $value | |
* @return array | |
*/ | |
function array_set(&$array, $key, $value) | |
{ | |
if (is_null($key)) return $array = $value; | |
$keys = explode('.', $key); | |
while (count($keys) > 1) | |
{ | |
$key = array_shift($keys); | |
// 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; | |
} | |
} | |
if ( ! function_exists('array_sort')) | |
{ | |
/** | |
* Sort the array using the given callback. | |
* | |
* @param array $array | |
* @param callable $callback | |
* @param int $options | |
* @param bool $descending | |
* @return array | |
*/ | |
function array_sort($array, callable $callback, $options = SORT_REGULAR, $descending = false) | |
{ | |
$results = []; | |
if ( ! (! is_string($callback) && is_callable($callback))) | |
{ | |
$oldCallback = $callback; | |
$callback = function($item) use ($oldCallback) | |
{ | |
return data_get($item, $oldCallback); | |
}; | |
} | |
// 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 ($array 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] = $array[$key]; | |
} | |
return $results; | |
} | |
} | |
if ( ! function_exists('array_where')) | |
{ | |
/** | |
* Filter the array using the given callback. | |
* | |
* @param array $array | |
* @param callable $callback | |
* @return array | |
*/ | |
function array_where($array, callable $callback) | |
{ | |
$filtered = []; | |
foreach ($array as $key => $value) | |
{ | |
if (call_user_func($callback, $key, $value)) $filtered[$key] = $value; | |
} | |
return $filtered; | |
} | |
} | |
if ( ! function_exists('data_get')) | |
{ | |
/** | |
* Get an item from an array or object using "dot" notation. | |
* | |
* @param mixed $target | |
* @param string $key | |
* @param mixed $default | |
* @return mixed | |
*/ | |
function data_get($target, $key, $default = null) | |
{ | |
if (is_null($key)) return $target; | |
foreach (explode('.', $key) as $segment) | |
{ | |
if (is_array($target)) | |
{ | |
if ( ! array_key_exists($segment, $target)) | |
{ | |
return value($default); | |
} | |
$target = $target[$segment]; | |
} | |
elseif ($target instanceof ArrayAccess) | |
{ | |
if ( ! isset($target[$segment])) | |
{ | |
return value($default); | |
} | |
$target = $target[$segment]; | |
} | |
elseif (is_object($target)) | |
{ | |
if ( ! isset($target->{$segment})) | |
{ | |
return value($default); | |
} | |
$target = $target->{$segment}; | |
} | |
else | |
{ | |
return value($default); | |
} | |
} | |
return $target; | |
} | |
} | |
if ( ! function_exists('value')) | |
{ | |
/** | |
* Return the default value of the given value. | |
* | |
* @param mixed $value | |
* @return mixed | |
*/ | |
function value($value) | |
{ | |
return $value instanceof Closure ? $value() : $value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment