在PHP中合并2个数组,仅保留第一个数组中的键

Car*_*rlo 1 php arrays array-merge

我有这两个数组:

$list = [
    'fruit' => [],
    'animals' => [],
    'objects' => [],
];

$dataArray = [
    'fruit' => 'apple',
    'animals' => ['dog', 'cat'],
    'asd' => 'bla'
];
Run Code Online (Sandbox Code Playgroud)

我要合并它们,以便最后的$ list是:

[fruit] => Array
    (
        [0] => apple
    )

[animals] => Array
    (
        [0] => dog
        [1] => cat
    )

[objects] => Array
    (
    )
Run Code Online (Sandbox Code Playgroud)

因此,注意事项:

  1. 即使'fruit'只有一个元素,它仍然是$ list中的数组
  2. $ list中缺少的键(“ asd”键)将被忽略
  3. 即使没有值,没有值的键也会保留

使用array_merge不起作用:

$merged = array_merge($list, $dataArray);

[fruit] => apple
[animals] => Array
    (
        [0] => dog
        [1] => cat
    )

[objects] => Array
    (
    )

[asd] => bla
Run Code Online (Sandbox Code Playgroud)

我设法得到我想要的东西:

foreach ($dataArray as $key => $value) {
    if (isset($list[$key])) {
        if (is_array($value)) {
            $list[$key] = $value;
        }
        else {
            $list[$key] = [$value];
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

但是我想知道是否有更清洁的方法来执行此操作,或者是否有其他我不知道的php函数。

iai*_*inn 5

您可以通过几个步骤来实现:

$result = array_intersect_key($dataArray, $list);
Run Code Online (Sandbox Code Playgroud)

这将返回一个包含第一个数组中所有元素的数组,然后根据第二个中的键进行过滤。这给您:

Array
(
  [fruit] => apple
  [animals] => Array
    (
        [0] => dog
        [1] => cat
    )
)
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下方法从第一个数组重新添加缺少的键:

$result + $list;
Run Code Online (Sandbox Code Playgroud)

+运算符和运算符之间的区别在于array_merge,前者不会使用第二个数组中的值覆盖第一个数组。它将仅添加任何缺少的元素。

在一行中,结果为:

$result = array_intersect_key($dataArray, $list) + $list;
Run Code Online (Sandbox Code Playgroud)

您可以在此处查看它的运行情况:https : //eval.in/865733

编辑:对不起,完全错过了有关将元素保留为数组的部分。如果它们将始终是数组,则可以添加一个快速的单行,例如:

$result = array_map(function ($e) { return (array) $e; }, $result);
Run Code Online (Sandbox Code Playgroud)

它将所有顶级元素转换为数组。如果您的逻辑比这更复杂,那么我不确定您是否会找到一种使用内置函数的方法。


axi*_*iac 2

第二条规则( “2. ( key)中缺少的键$list'asd'将被忽略” )告诉我要迭代$list,而不是$dataArray。如果$dataArray比 更大$list,则迭代它是浪费时间,因为它的大部分元素都被忽略。

您的规则没有解释$list当元素不为空时如何处理它们(我假设它们始终是数组,否则游戏会发生变化并且变得太复杂而无法提供通用代码来处理它)。

我建议的代码如下所示:

// Build the result in $result
// (you can modify $list as well if you prefer it that way)
$result = array();

// 2. keys missing from $list ('asd' key) are simply ignored
// iterate over the keys of $list, handle only the keys present in $dataArray
foreach ($list as $key => $value) {
    if (array_key_exists($dataArray, $key)) {
        // $key is present in $dataArray, use the value from $dataArray
        $value = $dataArray[$key];

        // 1. even if 'fruit' had only one element, is still an array in $list
        if (! is_array($value)) {
            $value = array($value);
        }
    }

    // 3. keys with no values are still kept, even if empty
    // if the key is not present in $dataArray, its value from $list is used
    $result[$key] = $value;
}
Run Code Online (Sandbox Code Playgroud)

如果将块移到块if (! is_array($value))之外,if (array_key_exists())它将转换为数组,这些值也不是数组,并且与(例如)$list中不存在的键关联。这样,代码运行后, 的所有值都是数组。$dataArray$list['objects']$result


你的代码也很好。除了迭代 over$list和 not over之外$dataArray,没有办法让它更快或更容易以壮观的方式阅读。我在这里建议的代码只是编写相同内容的另一种方式。