合并具有相同键的数组

61

在一款软件中,我使用array_merge函数合并了两个数组。但我需要将同一个数组(当然是具有相同键的数组)添加到现有数组中。

问题:

 $A = array('a' => 1, 'b' => 2, 'c' => 3);
 $B = array('c' => 4, 'd'=> 5);

 array_merge($A, $B);

 // result
 [a] => 1 [b] => 2 [c] => 4 [d] => 5

正如你所看到的,'c' => 3 被遗漏了。

那么我应该如何合并所有具有相同键的元素呢?


5
数组应该具有唯一的键值,这是数组的基本属性。 - xkeshav
8
你如何想象一个有两个相同键的数组? - Nemoden
就像他们所说的,键必须是唯一的。考虑使用二维数组代替关联数组,这样就可以在没有任何冲突的情况下合并它们。例如:array(array('a', 1), array('b', 2), array('c', 3), array('c', 4), array('d', 5)) - joelhardi
@Nemoden - 是的,这太奇怪了。但是我的DB类需要将WHERE和PARAMS合并到mysqli中进行绑定。无论如何,我需要将它们合并 :) - kuzey beytar
@kuzey 这个问题没有提供 [mcve],这导致了回答的发布会得到不同的结果。通过评论澄清您的情况(而不是进行[编辑]),读者将很难理解哪种类型的答案是适当的。您的问题仍然缺乏确切的期望结果。 - mickmackusa
我同意之前的发帖者(@mickmackusa)认为这个问题需要澄清。 - Sybille Peters
6个回答

55
你需要使用 array_merge_recursive 代替 array_merge。当然,在数组中只能有一个键等于 'c',但相关的值将是一个包含 34 的数组。

1
嗯...奇怪...我把array_merge改成了array_merge_recursive,但结果却相同(数组键被重新编号)。在PHP.net网站上,在array_merge下的示例#3中有一个评论:“_如果您想将第二个数组的数组元素附加到第一个数组中而不覆盖第一个数组中的元素并且不重新索引,请使用+数组联合运算符_”。在我的情况下,这是正确的。你在哪里读到array_merge_recursive不会重新编号键? - trejder
@trejder:这个问题中没有整数键,因此重新索引不适用于此。我考虑到了这一点来回答的。 - Jon
2
@Jon,你提供的答案链接已经失效了。如果你还有代码的话,能否请将它内嵌到回复中呢? - Adam Cameron
@AdamCameron 使用问题中的代码,只需将“普通”版本替换为array_merge_recursive - Jon
@Elyor array_mergearray_merge_recursive的文档记录了它们在处理字符串和整数键时具有不同的行为,这是有充分理由的:如果它们没有区别对待,那么array_merge([1], [2])的结果将是[0 => 2],这至少是“意外”的。因此,它们假设如果您有整数键,则这些键并不重要。如果您有重要的整数键,则必须提供显式逻辑来考虑这一点。 - Jon

44

尝试使用array_merge_recursive

$A = array('a' => 1, 'b' => 2, 'c' => 3);
$B = array('c' => 4, 'd'=> 5);
$c = array_merge_recursive($A,$B);

echo "<pre>";
print_r($c);
echo "</pre>";

将返回

Array
(
    [a] => 1
    [b] => 2
    [c] => Array
        (
            [0] => 3
            [1] => 4
        )

    [d] => 5
)

7
$arr1 = array(
   "0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
   "1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
   "2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
   "3" => array("fid" => 1, "tid" => 7, "name" => "Xi"),
   "4" => array("fid" => 2, "tid" => 9, "name" => "Xigua")
);

如果你想将这个数组转换成以下形式:

$arr2 = array(
   "0" => array(
          "0" => array("fid" => 1, "tid" => 1, "name" => "Melon"),
          "1" => array("fid" => 1, "tid" => 4, "name" => "Tansuozhe"),
          "2" => array("fid" => 1, "tid" => 6, "name" => "Chao"),
          "3" => array("fid" => 1, "tid" => 7, "name" => "Xi")
    ),

    "1" => array(
          "0" =>array("fid" => 2, "tid" => 9, "name" => "Xigua")
     )
);

所以,我的答案将会是这样的:
$outer_array = array();
$unique_array = array();
foreach($arr1 as $key => $value)
{
    $inner_array = array();

    $fid_value = $value['fid'];
    if(!in_array($value['fid'], $unique_array))
    {
            array_push($unique_array, $fid_value);
            unset($value['fid']);
            array_push($inner_array, $value);
            $outer_array[$fid_value] = $inner_array;


    }else{
            unset($value['fid']);
            array_push($outer_array[$fid_value], $value);

    }
}
var_dump(array_values($outer_array));

希望这个答案能够在某个时候对某个人有所帮助。


3

我刚刚写了这个函数,它应该能帮到你,但它执行的是左连接。

public function mergePerKey($array1,$array2)
    {
        $mergedArray = [];

        foreach ($array1 as $key => $value) 
        {
            if(isset($array2[$key]))
             {
               $mergedArray[$value] = null;

               continue;
             }
            $mergedArray[$value] = $array2[$key];
        }

        return $mergedArray;
    }

2
请解释您的代码片段并包含一个可工作的演示链接。 - mickmackusa
1
我赞同解释代码片段的建议。但是我不认为在这里绝对需要一个可工作的演示链接。(此外,当提问者没有费心更新问题以使其更清晰时,回答如何有用(除了礼貌地要求这样做的评论)- 真的不太清楚这个问题的预期结果是什么)。 - Sybille Peters

3
 $A = array('a' => 1, 'b' => 2, 'c' => 3);
 $B = array('c' => 4, 'd'=> 5);
 $C = array_merge_recursive($A, $B);
 $aWhere = array();
 foreach ($C as $k=>$v) {

    if (is_array($v)) {
        $aWhere[] = $k . ' in ('.implode(', ',$v).')';
    }
    else {
        $aWhere[] = $k . ' = ' . $v;
    }
 }
 $where = implode(' AND ', $aWhere);
 echo $where;

这个答案是否偏离了所问的问题?为什么我看到了“where”和“in ()”? - mickmackusa
@mickmackusa,对原问题的一些评论表明该问题与语句有关。我会假设该问题已被编辑过了。即使如此,我的答案仍然与问题同步,因为它包括使用array_merge_recursive的可行解决方案。 - Nemoden
啊,我明白你回答所涉及的评论了。这个答案缺少教育性的解释。在评论中解释说这个答案没有实现安全查询实践并不理想。在阅读你的答案之前,我没有看到这个评论。 - mickmackusa

-1

数组中的两个条目不能共享一个键,您需要更改重复项的键。


可以在问题下面发表评论或投票关闭为“需要澄清”来表达问题不清楚的意思。 - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接