【问题标题】:Merge a multidimensional array by associative value按关联值合并多维数组
【发布时间】:2020-02-08 22:26:14
【问题描述】:

我搜索了很多 SOF 线程,但似乎没有人坚持我的问​​题。什么是有线的,因为这应该是一个很好讨论的问题:)

也许我在寻找错误的东西......

场景:

我有 2 个数组

$a = [ 
    ['id' => 5, 'name' => 'bruce'],
    ['id' => 7, 'name' => 'wayne']
];
// 2 elements

$b = [
    ['id' => 6, 'name' => 'chuck'],
    ['id' => 8, 'name' => 'norris'],
    ['id' => 7, 'name' => 'wayne'] //also exists in array $a
];
// 3 elements

我的目标是

$c = [
    ['id' => 6, 'name' => 'chuck'],
    ['id' => 8, 'name' => 'norris'],
    ['id' => 7, 'name' => 'wayne'],
    ['id' => 5, 'name' => 'bruce']
];
// 4 elements (no duplicates)

我真的不关心数组中的顺序,但我想将两者合并为一个,而不是重复。

我尝试了 array_mergearray_merge_recursive。没有人工作。可能是因为函数不知道标识每个条目的标识符。有没有简单的解决方案,还是我真的必须为此创建一个自己的方法/函数?

也许有一个我可以使用的闭包?

【问题讨论】:

  • 你不会考虑一个闭包,写你自己的函数吗?

标签: php merge closures array-merge


【解决方案1】:

您可以使用非常简单的 PHP 内置函数来做到这一点

$c = array_unique(array_merge($a,$b), SORT_REGULAR);
print_r( $c )

print_r 的输出是

Array
(
    [0] => Array
        (
            [id] => 5
            [name] => bruce
        )

    [1] => Array
        (
            [id] => 7
            [name] => wayne
        )

    [2] => Array
        (
            [id] => 6
            [name] => chuck
        )

    [3] => Array
        (
            [id] => 8
            [name] => norris
        )

)

【讨论】:

  • 这正是我想要的!非常感谢:)
  • 我的数组内容有点复杂,但这就是应该做的:)
【解决方案2】:
$temp = array_merge($b, $a);
foreach ($temp as $v) {
    $c[$v['id']] = $v;
}

如果找到相同的id,则$c中的元素将被覆盖

【讨论】:

  • 这正是我对 do i really have to create an own method/function 的意思,但对于短代码仍然 +1 :)
  • 如果你只想合并数组,你可以给 $a 和 $b 数组字符串索引并使用 array_merge ` $a = [` ` "i5"=>['id' => 5, 'name' => 'bruce'],` ` "i7"=>['id' => 7, 'name' => 'wayne']` ` ];` $b = [ "i6"=> ['id' => 6, 'name' => 'chuck'], "i8"=>['id' => 8, 'name' => 'norris'], "i7"=>['id' => 7, '名字' => '韦恩'] ]; $c=array_merge($a, $b); `
  • 我得到的数据是按原样定义的。所以我得到的是数字而不是字符串 :) 但是谢谢你的努力 :)
  • 这很好,如果 id 和名称总是配对相同。
【解决方案3】:

这是一种在键排序后使用序列化散列每个数组的方法:

<?php

$a = [ 
    ['id' => 5, 'name' => 'bruce'],
    ['id' => 7, 'name' => 'wayne']
];

$b = [
    ['id' => 6, 'name' => 'chuck'],
    ['name' => 'wayne', 'id' => 7],
    ['id' => 8, 'name' => 'norris']
];
$merged = array_merge($a, $b);

foreach($merged as $k => $v) {
    ksort($v);
    $hashes[$k] = serialize($v);
}
$hashes = array_unique($hashes);
var_export(array_intersect_key($merged, $hashes));

输出:

array (
    0 => 
    array (
      'id' => 5,
      'name' => 'bruce',
    ),
    1 => 
    array (
      'id' => 7,
      'name' => 'wayne',
    ),
    2 => 
    array (
      'id' => 6,
      'name' => 'chuck',
    ),
    4 => 
    array (
      'id' => 8,
      'name' => 'norris',
    ),
  )

【讨论】:

  • 有点长的来源,我想因为在这个答案之前我找不到解决方案,因为文档原因是好的:) 猜猜有很多方法导致 Rom :D 有些更长,有些更短: )
  • 这可能会破坏具有不同顺序元素的更深的相似数组。 ksort 修复了平面数组的问题(否则需要递归 ksorting)。如果数组相似但顺序不同,array_unique / SORT_REGULAR 将中断,它将无法排序,然后不会丢弃相似的项目。这里可能不是问题。
【解决方案4】:

如果您在唯一的id 上为它们编制索引,那么只需添加它们。结果将在id上进行索引,这很方便:

$result = array_column($a, null, 'id') + array_column($b, null, 'id');

【讨论】:

  • 也可以,即使它的代码比接受的答案多一点。如果我做对了,唯一数组也会重新索引。所以用 array_values 包装你的会做同样的事情。 :D
  • 是的,但是如果像 id 这样独特的东西,那么个人更喜欢将其编入索引。
【解决方案5】:

我不知道它的性能如何,但只是使用我得到的 phps 数组操作函数:

>>> array_values(array_merge(array_combine(array_column($a, 'name'), $a), array_combine(array_column($b, 'name'), $b)));
=> [
     [
       "id" => 5,
       "name" => "bruce",
     ],
     [
       "id" => 7,
       "name" => "wayne",
     ],
     [
       "id" => 6,
       "name" => "chuck",
     ],
     [
       "id" => 8,
       "name" => "norris",
     ],
   ]

【讨论】:

  • 但这结果是一个 assoc 数组。好的,您选择了名称而不是 id,这是否也适用于整数 id?
  • array_values 电话中编辑 :)
  • 就像我对其他帖子的评论一样,猜想有很多方法可以导致 Rom :D 有些更长,有些更短:) 出于文档原因,为此答案 +1
猜你喜欢
  • 2011-11-26
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
相关资源
最近更新 更多