仅根据新键合并两个多维数组
Merge two multidimensional arrays based on new keys only
有没有办法合并这些数组:
// saved settings by the user
$arr1 = [
'options' => [
'first' => 1,
'second' => 2,
'third' => 3,
]
];
// new option schema (new keys added)
$arr2 = [
'options' => [
'first' => 1,
'second' => 212,
'fourth' => 4
]
];
得到如下输出:
$arr3 = [
'options' => [
'first' => 1, // nothing do to, "first" key already exists
'second' => 2, // nothing to do, "second" key exists (user already saved "second" with value 2, so we omit value 212)
// "third" option got removed from new schema, no longer needed in the app, so may be removed from User settings as well
'fourth' => 4 // this key is new, so let's add it to the final result
]
];
基本上我尝试了 array_merge
或 array_merge_recursive
但是它们合并了所有密钥而不是仅合并新密钥,因此它覆盖了用户设置。
当然源数组要复杂得多,里面有很多多维数组。
有没有办法让它变得简单或图书馆可以处理?
可以用递归函数来完成。新结构(本例中的 $arr2
)定义了结果中存在的键。如果旧结构在新结构中的相应键上有一个值,它将被使用。否则,将使用新结构中的值。因为您只查看新结构中存在的键,旧结构中不再存在的任何键都不会包括在内。
function update($newKeys, $oldData) {
$result = [];
// iterate only new structure so obsolete keys won't be included
foreach ($newKeys as $key => $value) {
// use the old value for the new key if it exists
if (isset($oldData[$key])) {
if (is_array($oldData[$key]) && is_array($value)) {
// if the old and new values for the key are both arrays, recurse
$result[$key] = merge($value, $oldData[$key]);
} else {
// otherwise, just use the old value
$result[$key] = $oldData[$key];
}
// use the new value if the key doesn't exist in the old values
} else {
$result[$key] = $value;
}
}
return $result;
}
$result = update($arr2, $arr1);
我只会在完全关联的结构上使用它。如果任何内部数组是键无关紧要的基本索引数组,则必须向函数添加一些内容以防止它弄乱它们。
有没有办法合并这些数组:
// saved settings by the user
$arr1 = [
'options' => [
'first' => 1,
'second' => 2,
'third' => 3,
]
];
// new option schema (new keys added)
$arr2 = [
'options' => [
'first' => 1,
'second' => 212,
'fourth' => 4
]
];
得到如下输出:
$arr3 = [
'options' => [
'first' => 1, // nothing do to, "first" key already exists
'second' => 2, // nothing to do, "second" key exists (user already saved "second" with value 2, so we omit value 212)
// "third" option got removed from new schema, no longer needed in the app, so may be removed from User settings as well
'fourth' => 4 // this key is new, so let's add it to the final result
]
];
基本上我尝试了 array_merge
或 array_merge_recursive
但是它们合并了所有密钥而不是仅合并新密钥,因此它覆盖了用户设置。
当然源数组要复杂得多,里面有很多多维数组。
有没有办法让它变得简单或图书馆可以处理?
可以用递归函数来完成。新结构(本例中的 $arr2
)定义了结果中存在的键。如果旧结构在新结构中的相应键上有一个值,它将被使用。否则,将使用新结构中的值。因为您只查看新结构中存在的键,旧结构中不再存在的任何键都不会包括在内。
function update($newKeys, $oldData) {
$result = [];
// iterate only new structure so obsolete keys won't be included
foreach ($newKeys as $key => $value) {
// use the old value for the new key if it exists
if (isset($oldData[$key])) {
if (is_array($oldData[$key]) && is_array($value)) {
// if the old and new values for the key are both arrays, recurse
$result[$key] = merge($value, $oldData[$key]);
} else {
// otherwise, just use the old value
$result[$key] = $oldData[$key];
}
// use the new value if the key doesn't exist in the old values
} else {
$result[$key] = $value;
}
}
return $result;
}
$result = update($arr2, $arr1);
我只会在完全关联的结构上使用它。如果任何内部数组是键无关紧要的基本索引数组,则必须向函数添加一些内容以防止它弄乱它们。