From f10278e1d9ff8804062b2c786888c3f0fbe763d9 Mon Sep 17 00:00:00 2001 From: Peter Scopes Date: Fri, 11 May 2018 11:53:52 +0100 Subject: [PATCH] Added Arr::collapse, Arr::column, and ArrDots::column --- src/Arr.php | 71 +++++++++++++++++++++++++++++++++----- src/ArrDots.php | 23 ++++++++++-- tests/Unit/ArrDotsTest.php | 40 +++++++++++++++++++++ tests/Unit/ArrTest.php | 56 ++++++++++++++++++++++++++++-- 4 files changed, 176 insertions(+), 14 deletions(-) diff --git a/src/Arr.php b/src/Arr.php index 904cb57..8594ffb 100644 --- a/src/Arr.php +++ b/src/Arr.php @@ -40,25 +40,31 @@ public static function isAssoc(array $array) /** * Divide an array into two arrays. One with keys and the other with values. * - * @param array $array + * @param Arrayable|array $array * * @return array [array, array] */ public static function divide($array) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return [array_keys($array), array_values($array)]; } /** * Flatten a multi-dimensional array into a single level. * - * @param array $array - * @param int $depth + * @param Arrayable|array $array + * @param int $depth * * @return array */ public static function flatten($array, $depth = INF) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return array_reduce($array, function ($result, $item) use ($depth) { if (!is_array($item)) { return array_merge($result, [$item]); @@ -70,58 +76,105 @@ public static function flatten($array, $depth = INF) }, []); } + /** + * Merge all elements of $array into a single array. + * + * @param ArrayAble|array $array + * @return array + */ + public static function collapse($array) + { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } + return array_merge(...$array); + } + /** * Get a subset of the items from $array that only contains $keys. * - * @param array $array + * @param Arrayable|array $array * @param int|string|array $keys * * @return array */ public static function only($array, $keys) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return array_intersect_key($array, array_flip((array) $keys)); } /** * Get a subset of the items from $array that contains all keys except $keys. * - * @param array $array + * @param ArrayAble|array $array * @param int|string|array $keys * * @return array */ public static function except($array, $keys) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return array_diff_key($array, array_flip((array) $keys)); } /** * Get a subset of items from $array that pass $callback test. * - * @param ArrayAccess|array $array - * @param callable $callback + * @param ArrayAble|array $array + * @param callable $callback * * @return array */ public static function filter($array, callable $callback) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH); } /** * Get a subset of unique items from $array. * - * @param ArrayAccess|array $array - * @param int $flag + * @param ArrayAble|array $array + * @param int $flag * * @return array */ public static function unique($array, $flag = SORT_STRING) { + if ($array instanceof ArrayAble) { + $array = $array->toArray(); + } return array_unique($array, $flag); } + /** + * Get the values from a single column in $array. + * An array of columns can be provided to chain call column. + * + * @param array $array + * @param string|array $columns + * @param string $indexKey Only applied to the last column + * @return array + * @see \array_column() + */ + public static function column($array, $columns, $indexKey = null) + { + $array = $array ?? []; + $columns = (array) $columns; + $last = array_pop($columns); + foreach ($columns as $column) { + $array = array_column($array, $column); + } + return array_column($array, $last, $indexKey); + } + /** * @param ArrayAccess|array $array * @param string|int $key diff --git a/src/ArrDots.php b/src/ArrDots.php index ad6b35f..b1f8de7 100644 --- a/src/ArrDots.php +++ b/src/ArrDots.php @@ -25,9 +25,10 @@ public static function implode($array, $prepend = '') foreach ($array as $key => $value) { if (is_array($value) && !empty($value)) { - $results = array_merge($results, static::implode($value, $prepend.$key.'.')); - } else { - $results[$prepend.$key] = $value; + $results = array_merge($results, static::implode($value, $prepend . $key . '.')); + } + else { + $results[$prepend . $key] = $value; } } @@ -52,6 +53,22 @@ public static function explode($array) return $results; } + /** + * Get the values from a single column in $array. + * An array of columns can be provided to chain call column. + * + * @param array $array + * @param string $dots + * @param string $indexKey Only applied to the last column + * @return array + * @see \MadeSimple\Arrays\Arr::column() + * @see \array_column() + */ + public static function column($array, $dots, $indexKey = null) + { + return Arr::column($array, explode('.', $dots), $indexKey); + } + /** * @param ArrayAccess|array $array * @param array|string $keys diff --git a/tests/Unit/ArrDotsTest.php b/tests/Unit/ArrDotsTest.php index 040cf9c..be009b5 100644 --- a/tests/Unit/ArrDotsTest.php +++ b/tests/Unit/ArrDotsTest.php @@ -47,6 +47,46 @@ public function testExplode() $this->assertEquals($multiDimensionalArray, ArrDots::explode($implodedArray)); } + public function testColumn() + { + $completeArray = [ + [ + 'one' => '1st one', + 'two' => ['alpha' => '1st two alpha', 'beta' => '1st two beta', 'id' => '1A'], + 'three' => [['gamma' => '1st gamma', 'epsilon' => '1st epsilon']] + ], + [ + 'one' => '2nd one', + 'two' => ['alpha' => '2nd two alpha', 'beta' => '2nd two beta', 'id' => '2B'], + 'three' => [['gamma' => '2nd gamma', 'epsilon' => '2nd epsilon']] + ], + [ + 'one' => '3rd one', + 'two' => ['alpha' => '3rd two alpha', 'beta' => '3rd two beta', 'id' => '3C'], + 'three' => [['gamma' => '3rd gamma', 'epsilon' => '3rd epsilon']] + ], + ]; + $partialArray1 = [ + '1st one', + '2nd one', + '3rd one', + ]; + $partialArray2 = [ + '1A' => '1st two alpha', + '2B' => '2nd two alpha', + '3C' => '3rd two alpha', + ]; + $partialArray3 = [ + '1st epsilon', + '2nd epsilon', + '3rd epsilon', + ]; + + $this->assertEquals($partialArray1, ArrDots::column($completeArray, 'one')); + $this->assertEquals($partialArray2, ArrDots::column($completeArray, 'two.alpha', 'id')); + $this->assertEquals($partialArray3, ArrDots::column($completeArray, 'three.0.epsilon')); + } + public function testRemove() { $completeArray = [ diff --git a/tests/Unit/ArrTest.php b/tests/Unit/ArrTest.php index eba6e7b..b81ab0c 100644 --- a/tests/Unit/ArrTest.php +++ b/tests/Unit/ArrTest.php @@ -59,6 +59,18 @@ public function testFlatten() $this->assertEquals($flattenedArray, Arr::flatten($multiDimensionalArray)); } + public function testCollapse() + { + $original = [ + ['alpha'], + ['beta'], + ['gamma'], + ]; + $collapsed = ['alpha', 'beta', 'gamma']; + + $this->assertEquals($collapsed, Arr::collapse($original)); + } + public function testOnly() { $completeArray = [ @@ -126,10 +138,10 @@ public function testFilter() })); } - public function unique() + public function testUnique() { $completeArray = [3,3, 5,5,5,5, 7,7,7,7,7,7, 9,9,9,9,9,9,9,9]; - $filteredArray = [3, 5, 7, 9]; + $filteredArray = [0 => 3, 2 => 5, 6 => 7, 12 => 9]; $this->assertEquals($filteredArray, Arr::unique($completeArray)); @@ -137,6 +149,46 @@ public function unique() $this->assertEquals($filteredArray, Arr::unique($completeDots)); } + public function testColumn() + { + $completeArray = [ + [ + 'one' => '1st one', + 'two' => ['alpha' => '1st two alpha', 'beta' => '1st two beta', 'id' => '1A'], + 'three' => [['gamma' => '1st gamma', 'epsilon' => '1st epsilon']] + ], + [ + 'one' => '2nd one', + 'two' => ['alpha' => '2nd two alpha', 'beta' => '2nd two beta', 'id' => '2B'], + 'three' => [['gamma' => '2nd gamma', 'epsilon' => '2nd epsilon']] + ], + [ + 'one' => '3rd one', + 'two' => ['alpha' => '3rd two alpha', 'beta' => '3rd two beta', 'id' => '3C'], + 'three' => [['gamma' => '3rd gamma', 'epsilon' => '3rd epsilon']] + ], + ]; + $partialArray1 = [ + '1st one', + '2nd one', + '3rd one', + ]; + $partialArray2 = [ + '1A' => '1st two alpha', + '2B' => '2nd two alpha', + '3C' => '3rd two alpha', + ]; + $partialArray3 = [ + '1st epsilon', + '2nd epsilon', + '3rd epsilon', + ]; + + $this->assertEquals($partialArray1, Arr::column($completeArray, 'one')); + $this->assertEquals($partialArray2, Arr::column($completeArray, ['two', 'alpha'], 'id')); + $this->assertEquals($partialArray3, Arr::column($completeArray, ['three', 0, 'epsilon'])); + } + public function testExists() { $array = [