在特定键上合并两个多维数组

时间:2012-12-02 13:07:10

标签: php multidimensional-array array-merge

假设我有以下数组:

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

        [1] => Array
            (
                [id] => 4
                [name] => Computers
            )

        [3] => Array
            (
                [id] => 7
                [name] => Science

        [4] => Array
            (
                [id] => 1
                [name] => Sports
            )
    )

第二个:

Array
    (
        [0] => Array
            (
                [id] => 1
                [title] => Sport
            )

        [1] => Array
            (
                [id] => 7
                [title] => Sci
            )

        [3] => Array
            (
                [id] => 4
                [title] => Comp

        [4] => Array
            (
                [id] => 5
                [title] => Edu
            )
    )

期望的输出是:

Array
    (
        [0] => Array
            (
                [id] => 5
                [name] => Education
                [title] => Edu
            )

        [1] => Array
            (
                [id] => 4
                [name] => Computers
                [title] => Comp
            )

        [3] => Array
            (
                [id] => 7
                [name] => Science
                [title] => Sci

        [4] => Array
            (
                [id] => 1
                [name] => Sports
                [title] => Sport
            )
    )

我设法将这些数组合并为:

foreach($first as $key => $value){
    $result[$key] = array_merge($first[$key], $second[$key]);
}

但输出未正确组合:

Array
    (
        [0] => Array
            (
                [id] => 5
                [name] => Education
                [title] => Sport
            )

        [1] => Array
            (
                [id] => 4
                [name] => Computers
                [title] => Sci
            )

        [3] => Array
            (
                [id] => 7
                [name] => Science
                [title] => Comp

        [4] => Array
            (
                [id] => 1
                [name] => Sports
                [title] => Edu
            )
    )

问题是我想在同一个id上合并这些数组。 期望的输出排序应与第一个数组中的相同。

我怎样才能做到这一点?非常感谢任何帮助。

7 个答案:

答案 0 :(得分:9)

您可以执行嵌套循环并检查id值是否匹配,然后将title添加到$first(或name$second)< / p>

foreach($first as $key => $value){
    foreach($second as $value2){
        if($value['id'] === $value2['id']){
            $first[$key]['title'] = $value2['title'];
        }               
    }
}

答案 1 :(得分:2)

您的代码工作正常。你的期望是完全错误的。例如,在一个数组中,第4个元素id保持1,但在另一个数组中,第4个元素id为5,所以你的“将这些数组合并到同一个id”没有任何意义通过将第4个元素合并为一个,你也可以合并它们的子元素,并且由于id在两个数组中使用,因此一旦值必须消失,因为数组中不能有两个相等的键。

修改

您必须手动合并,因为PHP功能基于进行合并,而您想根据内容进行合并

$result = array();
foreach( $arrayA as $keyA => $valA ) {
  foreach( $arrayB as $keyB => $valB ) {
     if( $valA['id'] == $valB['id'] ) {
       $result[$keyA] = $valA + $valB;

       // or if you do not care output keys, just
       // $result[] = $valA + $valB;
     }
  }
}

答案 2 :(得分:1)

只要两个数组中都包含每个id,那么通过'id'字段对两个数组进行排序,然后让php进行合并呢?

function cmp($a, $b) {
  return ((int) $a['id'] < (int) $b['id']) ? -1 : 1;
}

usort($array1, 'cmp');
usort($array2, 'cmp');

$result = array_merge($array1, $array2);

没有测试过代码,但它证明了这个想法。

答案 3 :(得分:1)

不要在foreach中使用foreach,当数组太大时可能会太慢。

$idArray = array_column($secondArray,'title','id');
foreach($firstArray as $key => $val){
  $firstArray[$key]['title'] = (isset($idArray[$val['id']]) ? $idArray[$val['title'] : 'some title';
}

答案 4 :(得分:1)

提供PHP 5.5+中可用的替代方法。

由于两个数组的顺序不同,因此请首先使用array_replace_recusrive通过id对数组进行索引。

这将使您可以在id索引数组上使用https://3v4l.org/ndv2j

array_replace_recursive将合并与两个数组集的索引关联匹配的数组中的值。

(可选)使用array_values重新索引数组,删除id索引关联。

示例{{3}}

$first = array_column($first, null, 'id');
$second = array_column($second, null, 'id');
$result = array_values(array_replace_recursive($first, $second));

结果

Array
(
    [0] => Array
        (
            [id] => 5
            [name] => Education
            [title] => Edu
        )

    [1] => Array
        (
            [id] => 4
            [name] => Computers
            [title] => Comp
        )

    [2] => Array
        (
            [id] => 7
            [name] => Science
            [title] => Sci
        )

    [3] => Array
        (
            [id] => 1
            [name] => Sports
            [title] => Sport
        )

)

答案 5 :(得分:1)

使用array_column的3参数形式通过second值重新索引id数组,然后循环遍历first数组,可以轻松完成此操作,合并匹配的second值的内容(如果存在):

$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
    $subject = array_merge($subject, $second[$subject['id']] ?? []);
}

输出:

Array
(
    [0] => Array
        (
            [id] => 5
            [name] => Education
            [title] => Edu
        )
    [1] => Array
        (
            [id] => 4
            [name] => Computers
            [title] => Comp
        )
    [3] => Array
        (
            [id] => 7
            [name] => Science
            [title] => Sci
        )
    [4] => Array
        (
            [id] => 1
            [name] => Sports
            [title] => Sport
        )
)

Demo on 3v4l.org

与Will B.的答案相比,它的优点是不重新索引first数组。由于也只有一个呼叫array_column而没有一个呼叫array_values,所以速度也稍快(我的测试显示〜10%)。

更新

实际上,通过使用array union operator+)可以进一步提高代码的速度(感谢@mickmackusa):

$second = array_column($second, null, 'id');
foreach ($first as &$subject) {
    $subject += $second[$subject['id']] ?? [];
}

此代码的输出与上述相同,但运行速度又提高了约10%。

Demo on 3v4l.org

答案 6 :(得分:0)

确保项目的顺序相同:

$items = array_map(function($itemFirstArray, $itemSecondArray) {
  return array_merge($itemFirstArray, $itemSecondArray);
}, $firstArray, $secondArray);