Skip to content

Commit

Permalink
Merge pull request #4787 from hperrin/master_hash_improvements
Browse files Browse the repository at this point in the history
Improvements to Hash::expand and Hash::merge. (master)
  • Loading branch information
markstory committed Oct 1, 2014
2 parents eac4e3d + be8c591 commit 5582edf
Showing 1 changed file with 41 additions and 12 deletions.
53 changes: 41 additions & 12 deletions lib/Cake/Utility/Hash.php
Expand Up @@ -622,6 +622,9 @@ public static function flatten(array $data, $separator = '.') {
*/
public static function expand($data, $separator = '.') {
$result = array();

$stack = array();

foreach ($data as $flat => $value) {
$keys = explode($separator, $flat);
$keys = array_reverse($keys);
Expand All @@ -634,7 +637,24 @@ public static function expand($data, $separator = '.') {
$k => $child
);
}
$result = self::merge($result, $child);

$stack[] = array($child, &$result);

while (!empty($stack)) {
foreach ($stack as $curKey => &$curMerge) {
foreach ($curMerge[0] as $key => &$val) {
if (!empty($curMerge[1][$key]) && (array)$curMerge[1][$key] === $curMerge[1][$key] && (array)$val === $val) {
$stack[] = array(&$val, &$curMerge[1][$key]);
} elseif ((int)$key === $key && isset($curMerge[1][$key])) {
$curMerge[1][] = $val;
} else {
$curMerge[1][$key] = $val;
}
}
unset($stack[$curKey]);
}
unset($curMerge);
}
}
return $result;
}
Expand All @@ -654,19 +674,28 @@ public static function expand($data, $separator = '.') {
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge
*/
public static function merge(array $data, $merge) {
$args = func_get_args();
$return = current($args);

while (($arg = next($args)) !== false) {
foreach ((array)$arg as $key => $val) {
if (!empty($return[$key]) && is_array($return[$key]) && is_array($val)) {
$return[$key] = self::merge($return[$key], $val);
} elseif (is_int($key) && isset($return[$key])) {
$return[] = $val;
} else {
$return[$key] = $val;
$args = array_slice(func_get_args(), 1);
$return = $data;

foreach ($args as &$curArg) {
$stack[] = array((array)$curArg, &$return);
}
unset($curArg);

while (!empty($stack)) {
foreach ($stack as $curKey => &$curMerge) {
foreach ($curMerge[0] as $key => &$val) {
if (!empty($curMerge[1][$key]) && (array)$curMerge[1][$key] === $curMerge[1][$key] && (array)$val === $val) {
$stack[] = array(&$val, &$curMerge[1][$key]);
} elseif ((int)$key === $key && isset($curMerge[1][$key])) {
$curMerge[1][] = $val;
} else {
$curMerge[1][$key] = $val;
}
}
unset($stack[$curKey]);
}
unset($curMerge);
}
return $return;
}
Expand Down

0 comments on commit 5582edf

Please sign in to comment.