Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

API: Add ArrayLib::flatten($array, $preserveKeys)

  • Loading branch information...
commit 718108969bbb3ab727b2740f4ca0781a431b3739 1 parent 3b72432
@wilr wilr authored
Showing with 104 additions and 22 deletions.
  1. +75 −22 core/ArrayLib.php
  2. +29 −0 tests/core/ArrayLibTest.php
View
97 core/ArrayLib.php
@@ -1,6 +1,8 @@
<?php
+
/**
* Library of static methods for manipulating arrays.
+ *
* @package framework
* @subpackage misc
*/
@@ -43,7 +45,10 @@ class ArrayLib {
* @return array
*/
public static function invert($arr) {
- if(!$arr) return false;
+ if(!$arr) {
+ return false;
+ }
+
$result = array();
foreach($arr as $columnName => $column) {
@@ -56,7 +61,7 @@ public static function invert($arr) {
}
/**
- * Return an array where the keys are all equal to the values
+ * Return an array where the keys are all equal to the values.
*
* @param $arr array
* @return array
@@ -70,7 +75,8 @@ public static function valuekey($arr) {
*/
public static function array_values_recursive($arr) {
$lst = array();
- foreach(array_keys($arr) as $k){
+
+ foreach(array_keys($arr) as $k) {
$v = $arr[$k];
if (is_scalar($v)) {
$lst[] = $v;
@@ -80,92 +86,115 @@ public static function array_values_recursive($arr) {
);
}
}
+
return $lst;
}
/**
- * Filter an array by keys (useful for only allowing certain form-input to be saved).
+ * Filter an array by keys (useful for only allowing certain form-input to
+ * be saved).
*
* @param $arr array
* @param $keys array
+ *
* @return array
*/
- public static function filter_keys($arr, $keys)
- {
- foreach ($arr as $key => $v) {
- if (!in_array($key, $keys)) {
+ public static function filter_keys($arr, $keys) {
+ foreach($arr as $key => $v) {
+ if(!in_array($key, $keys)) {
unset($arr[$key]);
}
}
+
return $arr;
}
/**
- * Determines if an array is associative by checking
- * for existing keys via array_key_exists().
+ * Determines if an array is associative by checking for existing keys via
+ * array_key_exists().
+ *
* @see http://nz.php.net/manual/en/function.is-array.php#76188
*
* @param array $arr
+ *
* @return boolean
*/
public static function is_associative($arr) {
if(is_array($arr) && ! empty($arr)) {
for($iterator = count($arr) - 1; $iterator; $iterator--) {
- if (!array_key_exists($iterator, $arr)) return true;
+ if (!array_key_exists($iterator, $arr)) {
+ return true;
+ }
}
+
return !array_key_exists(0, $arr);
}
+
return false;
}
/**
* Recursively searches an array $haystack for the value(s) $needle.
+ *
* Assumes that all values in $needle (if $needle is an array) are at
* the SAME level, not spread across multiple dimensions of the $haystack.
*
* @param mixed $needle
* @param array $haystack
* @param boolean $strict
+ *
* @return boolean
*/
public static function in_array_recursive($needle, $haystack, $strict = false) {
- if(!is_array($haystack)) return false; // Not an array, we've gone as far as we can down this branch
-
- if(in_array($needle, $haystack, $strict)) return true; // Is it in this level of the array?
- else {
- foreach($haystack as $obj) { // It's not, loop over the rest of this array
- if(self::in_array_recursive($needle, $obj, $strict)) return true;
+ if(!is_array($haystack)) {
+ return false;
+ }
+
+ if(in_array($needle, $haystack, $strict)) {
+ return true;
+ } else {
+ foreach($haystack as $obj) {
+ if(self::in_array_recursive($needle, $obj, $strict)) {
+ return true;
+ }
}
}
- return false; // Never found $needle :(
+ return false;
}
/**
* Recursively merges two or more arrays.
*
- * Behaves similar to array_merge_recursive(), however it only merges values when both are arrays
- * rather than creating a new array with both values, as the PHP version does. The same behaviour
- * also occurs with numeric keys, to match that of what PHP does to generate $_REQUEST.
+ * Behaves similar to array_merge_recursive(), however it only merges
+ * values when both are arrays rather than creating a new array with
+ * both values, as the PHP version does. The same behaviour also occurs
+ * with numeric keys, to match that of what PHP does to generate $_REQUEST.
+ *
+ * @param array $array
*
- * @param array $array, ...
* @return array
*/
public static function array_merge_recursive($array) {
$arrays = func_get_args();
$merged = array();
+
if(count($arrays) == 1) {
return $array;
}
+
while ($arrays) {
$array = array_shift($arrays);
+
if (!is_array($array)) {
trigger_error('ArrayLib::array_merge_recursive() encountered a non array argument', E_USER_WARNING);
return;
}
+
if (!$array) {
continue;
}
+
foreach ($array as $key => $value) {
if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key])) {
$merged[$key] = ArrayLib::array_merge_recursive($merged[$key], $value);
@@ -174,6 +203,30 @@ public static function array_merge_recursive($array) {
}
}
}
+
return $merged;
}
+
+ /**
+ * Takes an multi dimension array and returns the flattened version.
+ *
+ * @param array $array
+ * @param boolean $preserveKeys
+ *
+ * @return array
+ */
+ public static function flatten($array, $preserveKeys = true, &$out = array()) {
+ foreach($array as $key => $child) {
+ if(is_array($child)) {
+ $out = self::flatten($child, $preserveKeys, $out);
+ } else if($preserveKeys) {
+ $out[$key] = $child;
+ } else {
+ $out[] = $child;
+ }
+ }
+
+ return $out;
+ }
}
+
View
29 tests/core/ArrayLibTest.php
@@ -1,9 +1,11 @@
<?php
+
/**
* @package framework
* @subpackage tests
*/
class ArrayLibTest extends SapphireTest {
+
public function testInvert() {
$arr = array(
'row1' => array(
@@ -187,4 +189,31 @@ public function testArrayMergeRecursive() {
'Numeric keys should behave like string keys'
);
}
+
+ public function testFlatten() {
+ $options = array(
+ '1' => 'one',
+ '2' => 'two'
+ );
+
+ $expected = $options;
+
+ $this->assertEquals($expected, ArrayLib::flatten($options));
+
+ $options = array(
+ '1' => array(
+ '2' => 'two',
+ '3' => 'three'
+ ),
+ '4' => 'four'
+ );
+
+ $expected = array(
+ '2' => 'two',
+ '3' => 'three',
+ '4' => 'four'
+ );
+
+ $this->assertEquals($expected, ArrayLib::flatten($options));
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.