如何根据某些条件对多维数组求和?

How to sum multi-dimensional arrays based on some conditions?

 $arr = [ [
        '5'=>[
            'BG' => 50,
            'CH' => 60,
            'LG' => 50,
            'MT' => 40,
            'MO' => 80,
            'PH' => 60,
            'GE' =>null
        ]
    ], [
        '6'=>[
            'BG' => 90,
            'CH' => 60,
            'LG' => 60,
            'MT' => 50,
            'MO' =>null,
            'PH' => 50,
            'GE' =>null
        ]
    ],[
        '7'=>[
            'BG' => 80,
            'CH' => 55,
            'LG' => 65,
            'MT' => 50,
            'MO' =>null,
            'PH' => 50,
            'GE' => 55
        ]
    ]
  ];

我想对每个编号 5、6 和 7 的分数求和。 CH、PH、MO 和 LG 总是必须总结的。但是在总结了必修项目之后,我想根据以下条件来总结其他项目。 如果 MO 为空,则从 BG、MT 和 GE 中取最好的两个。如果 MO 不为空或大于或等于 0,我想从 BG、MT 或 GE 中取最好的一个。

因此汇总结果如下所示:

Array
(
  [5] => Array
    (
        [score] => 300
    )
[6] => Array
    (
        [score] => 310
    )
[7] => Array
    (
        [score] => 305
    )
)

我已经试过foreach,但我无法解决问题。我该如何解决这个问题?

在这里,我们可以先将我们的三个数组全部相加,然后根据条件进行相减,我们的代码如下所示,

$arr = [[
    '5' => [
        'BG' => 50,
        'CH' => 60,
        'LG' => 50,
        'MT' => 40,
        'MO' => 80,
        'PH' => 60,
        'GE' => null,
    ],
], [
    '6' => [
        'BG' => 90,
        'CH' => 60,
        'LG' => 60,
        'MT' => 50,
        'MO' => null,
        'PH' => 50,
        'GE' => null,
    ],
], [
    '7' => [
        'BG' => 80,
        'CH' => 55,
        'LG' => 65,
        'MT' => 50,
        'MO' => null,
        'PH' => 50,
        'GE' => 55,
    ],
],
];

$sum_arr = array();
foreach ($arr as $key => $arr2) {
    foreach ($arr2 as $key2 => $value) {
        $sum_arr[$key2]["score"] = array_sum(array_values($value));
        $temp = [$value["BG"], $value["MT"], $value["GE"]];
        arsort($temp);
        if ($value["MO"] === null) {
            $sum_arr[$key2]["score"] -= $temp[2];
        } elseif ($value["MO"] != null && $value["MO"] >= 0) {
            $sum_arr[$key2]["score"] -= $temp[2] + $temp[1];
        } else {
            continue;
        }

    }

}

var_dump($sum_arr);

要么我的代码中存在错误(这很可能),要么我没有正确理解 if 条件,或者所需的输出不太可能不正确。不过调试起来应该不难。

输出

array(3) {
  [5]=>
  array(1) {
    ["score"]=>
    int(300)
  }
  [6]=>
  array(1) {
    ["score"]=>
    int(310)
  }
  [7]=>
  array(1) {
    ["score"]=>
    int(300)
  }
}

这里有更核心的实现方式,请查看内联文档进行解释,

$keys  = array_flip(['BG', 'MT', 'GE']); // best of how many keys
$Ckeys = array_flip(['CH', 'PH', 'MO', 'LG']); // compulsory keys
foreach ($arr as $key => $value) {
    // use to pass parameters to reduce function during call
    $temp[key($value)] = array_reduce($value, function (&$result, $a) use ($keys, $Ckeys) {
        // if mo empty then best of two else best of one
        $bestHowMany = (!empty($a['MO']) ? 1 : 2);
        // fetching best of keys from $keys
        $t           = array_intersect_key($a, $keys);
        // reverse sort and maintains keys
        arsort($t);
        // fetch top $bestHowMany Values
        $largest2 = array_slice($t, 0, $bestHowMany);
        // fetch compulsory values from CKeys
        $t1       = array_intersect_key($a, $Ckeys);
        // sum by merging compulsory and best of $bestHowMany values
        return array_sum(array_merge($t1, $largest2));
    });
}

工作demo.

输出

Array
(
    [5] => 300
    [6] => 310
    [7] => 305
)