php合并基于相同特定键的2个数组

时间:2017-09-07 02:08:32

标签: php arrays merge

我有两种PHP语言数组:

Array
(
    [0] => Array
        (
            [amount] => 21600.00
            [rows] => 2
            [student_id] => 1
        )

)

Array
(
    [0] => Array
        (
            [amount] => 541990.00
            [rows] => 512
            [student_id] => 1
        )

    [1] => Array
        (
            [amount] => 347480.00
            [rows] => 281
            [student_id] => 2
        )

    [2] => Array
        (
            [amount] => 507400.00
            [rows] => 214
            [student_id] => 3
        )
)

我想基于相同的student_id值合并两个数组,所以我希望结果如下:

Array
(
    [0] => Array
        (
            [amount] => 563590.00
            [rows] => 514
            [student_id] => 1
        )

    [1] => Array
        (
            [amount] => 347480.00
            [rows] => 281
            [student_id] => 2
        )

    [2] => Array
        (
            [amount] => 507400.00
            [rows] => 214
            [student_id] => 3
        )
)

我已经尝试过array_merge和array_merge_recursive,但他们没有给我预期的结果,谢谢!

3 个答案:

答案 0 :(得分:1)

以下是解决问题的简单代码,

count($arr) > count($arr0) ? ($greater = $arr AND $smaller = $arr0) : ($smaller = $arr AND $greater = $arr0);
foreach ($greater as $key => &$value) {
    foreach ($smaller as $key1 => &$value1) {
        if($value['student_id'] == $value1['student_id']){
            $value['amount'] +=$value1['amount'];
            $value['rows'] +=$value1['rows'];
        }
    }
}

检查输出here

答案 1 :(得分:0)

关于组合查询的评论可能是更好的方法。

SELECT student_id, sum(amount) as amount, sum(rows) as rows 
from students
group by student_id;

但是,如果你不能通过查询来实现,PHP本身并不会将数组值一起添加(这没有意义)

这是你必须做的事情

function arrayMergeMatch(&$a, &$b)
{
    foreach ($a as $key => $value) {
        if (array_key_exists($key, $b)) {
            // there's a matching index in both a & b
            $a[$key] = [
                $a[$key]['amount'] += $b[$key]['amount'],
                $a[$key]['rows'] += $b[$key]['rows'],
                $a[$key]['student_id'],
            ];
        }
    }
}

$firstArray = $secondArray = [];

$firstArray[0] = [
    'amount' => 21600.00,
    'rows'   => 2,
    'student_id' => 1 
];


$secondArray[0] = [
    'amount' => 541990.00,
    'rows' => 512,
    'student_id' => 1,
];

$secondArray[1] = [
    'amount' => 347480.00,
    'rows' => 281,
    'student_id' => 2,
];

$secondArray[2] = [
    'amount' => 507400.00,
    'rows' => 214,
    'student_id' => 3,
];

$firstArrayLength  = count($x);
$secondArrayLength = count($y);

$combinedArray = null;

if ($firstArrayLength > $secondArrayLength) {
    // loop through x checking to see if there's a matching y
    arrayMergeMatch($firstArray, $secondArray);
    $combinedArray = $firstArray;
}
else {
    // y is longer than or equal to x, so loop through y, looking for matching
    // index in x
    arrayMergeMatch($secondArray, $firstArray);
    $combinedArray = $secondArray;
}

print_r($combinedArray);

答案 2 :(得分:0)

嵌套循环不是必需的。会有几种不同的样式,但任务的关键是创建一个结果数组,在迭代传入数据时临时用作查找数组。

为此,请使用 student_id 值分配临时键。当在结果数组中找到后遇到student_id时,只需将这些值添加到组中存储的相关值中即可。完成迭代后,使用 array_values() 重新索引结果。

函数风格:(Demo1) (Demo2 - likely slower)

var_export(
    array_values(
        array_reduce(
            $array2,
            function($result, $row) {
                if (!isset($result[$row['student_id']])) {
                    $result[$row['student_id']] = $row;
                } else {
                    $result[$row['student_id']]['amount'] += $row['amount'];
                    $result[$row['student_id']]['rows'] += $row['rows'];
                }
                return $result;
            },
            array_column($array1, null, 'student_id')
        )
    )
);

语言构造循环:(Demo1) (Demo2 - likely slower)

$result = array_column($array1, null, 'student_id');
foreach ($array2 as $row) {
    if (!isset($result[$row['student_id']])) {
        $result[$row['student_id']] = $row;
    } else {
        $result[$row['student_id']]['amount'] += $row['amount'];
        $result[$row['student_id']]['rows'] += $row['rows'];
    }
}
var_export(array_values($result));

应使用上述所有片段而不是其他已发布的答案,因为它们的迭代次数永远不会超过 m + n。以下是对其他答案的批评:

  • Rahul 的答案是使用嵌套循环——这意味着迭代次数将为 m*n(array1 中的行数乘以 array2 中的行数)——这是非常间接/低效的.即使使用了 break,它仍然不会像我的代码段那样直接/高效。

  • 科尔尼的回答完全忽略了对 student_id 值进行排序的要求(即使在修复了 $x$y 拼写错误之后)。这个基于 php 的答案完全不正确Proof. 不太重要的是,$b 不需要通过引用进行修改。