<?php
interface ModifierInterface
{
public function apply(array $data, string $key): array;
}
class ArrayHelper
{
public static function mergeReverse(...$args): array
{
return self::applyModifiers(self::performMergeReverse(...$args));
}
public static function merge(...$args): array
{
return self::applyModifiers(self::performMerge(...$args));
}
private static function performMergeReverse(...$args): array
{
$res = array_pop($args) ?: [];
while (!empty($args)) {
foreach (array_pop($args) as $k => $v) {
if (is_int($k)) {
if (array_key_exists($k, $res) && $res[$k] !== $v) {
$res[] = $v;
} else {
$res[$k] = $v;
}
} elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
$res[$k] = self::performMergeReverse($v, $res[$k]);
} elseif (!isset($res[$k])) {
$res[$k] = $v;
}
}
}
return $res;
}
private static function performMerge(...$args): array
{
$res = array_shift($args) ?: [];
while (!empty($args)) {
foreach (array_shift($args) as $k => $v) {
if (is_int($k)) {
if (array_key_exists($k, $res) && $res[$k] !== $v) {
$res[] = $v;
} else {
$res[$k] = $v;
}
} elseif (is_array($v) && isset($res[$k]) && is_array($res[$k])) {
$res[$k] = self::performMerge($res[$k], $v);
} else {
$res[$k] = $v;
}
}
}
return $res;
}
public static function applyModifiers(array $data): array
{
$modifiers = [];
foreach ($data as $k => $v) {
if ($v instanceof ModifierInterface) {
$modifiers[$k] = $v;
unset($data[$k]);
} elseif (is_array($v)) {
$data[$k] = self::applyModifiers($v);
}
}
foreach ($modifiers as $key => $modifier) {
$data = $modifier->apply($data, $key);
}
return $data;
}
}
$one = [
'f' => 'f1',
'b' => [
'b1' => 'b11',
'b2' => 'b33',
],
'g' => 'g1',
'h',
];
$two = [
'a' => 'a1',
'b' => [
'b1' => 'bv1',
'b2' => 'bv2',
],
'd',
];
$three = [
'a' => 'a2',
'c' => 'c1',
'b' => [
'b2' => 'bv22',
'b3' => 'bv3',
],
'e',
];
$result = ArrayHelper::merge($one, $two, $three);
var_export($result);
echo "\n\n";
$resultPop = ArrayHelper::mergeReverse($one, $two, $three);
var_export($resultPop);
- Output for 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.25, 8.4.1 - 8.4.12
- array (
'f' => 'f1',
'b' =>
array (
'b1' => 'bv1',
'b2' => 'bv22',
'b3' => 'bv3',
),
'g' => 'g1',
0 => 'h',
'a' => 'a2',
1 => 'd',
'c' => 'c1',
2 => 'e',
)
array (
'a' => 'a2',
'c' => 'c1',
'b' =>
array (
'b2' => 'bv22',
'b3' => 'bv3',
'b1' => 'bv1',
),
0 => 'e',
1 => 'd',
'f' => 'f1',
'g' => 'g1',
2 => 'h',
)
preferences:
160.8 ms | 408 KiB | 5 Q