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

时间:2019-06-02 19:18:30

标签: php arrays sorting multidimensional-array associative-array

 $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不为null或大于或等于0,我想从BG,MT或GE中选出最好的一个。

所以汇总结果如下:

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

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

2 个答案:

答案 0 :(得分:1)

这是实现此目标的更核心方法,请找到内联文档进行解释,

$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
)

答案 1 :(得分:0)

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

$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)
  }
}