多维数组删除带条件的重复键值

时间:2017-08-23 17:07:05

标签: php arrays loops multidimensional-array

我有一个像这样的数组:

$ratesData = [
    1 => [
        'id' => 1,
        'amount' => 2
    ],
    0 => [
        'id' => 1,
        'amount' => 1
    ],
    2 => [
        'id' => 1,
        'amount' => 3
    ],
    3 => [
        'id' => 2,
        'amount' => 2
    ]
];

我希望保留重复的id数组的数量最少,结果如下:

[
    0 => [
       'id' => 1,
       'amount' => 1
    ],
    1 => [
       'id' => 2,
       'amount' => 2
    ]
]

我有一个可以解决这个问题的代码,但我正在寻找一种优雅的方法来实现这一目标而不需要所有这些循环:

    foreach($ratesData as $firstLoopKey => $firstLoopValue) {
        foreach($ratesData as $secondLoopKey => $secondLoopValue) {
            if($firstLoopValue['id'] === $secondLoopValue['id'] && $firstLoopKey != $secondLoopKey ) {
                if ($ratesData[$secondLoopKey]['total_amount'] > $ratesData[$firstLoopKey]['total_amount']) {
                    $deleteElements[] = $secondLoopKey;
                }
            }
        }
    }

    if (isset($deleteElements)) {
        foreach ($deleteElements as $element) {
            unset($ratesData[$element]);
        }
    }

    $ratesData = array_values($ratesData);

    return $ratesData;

3 个答案:

答案 0 :(得分:1)

一些简单的解决方案:

// your source array
$ratesData = [];
// result array
$filtered = [];

foreach ($ratesData as $v) {
    $id = $v['id'];
    // if this is `$id`, which is not in `$filtered` yet
    // or value of `$filtered[$id]['amount']` is greater then current `$v`
    // then replace `$filtered[$id]` with current `$v`
    if (!isset($filtered[$id]) || $filtered[$id]['amount'] > $v['amount']) {
        $filtered[$id] = $v;
    }
}

echo'<pre>',print_r(array_values($filtered)),'</pre>';

答案 1 :(得分:1)

您可以按amount降序排序,然后按id提取数组索引,这样可以消除重写次数amount覆盖较高的重复项:

array_multisort(array_column($ratesData, 'amount'), SORT_DESC, $ratesData);
$ratesData = array_column($ratesData, null, 'id');

收率:

Array
(
    [1] => Array
        (
            [id] => 1
            [amount] => 1
        )
    [2] => Array
        (
            [id] => 2
            [amount] => 2
        )
)

我总是喜欢使用与唯一id相同的键来更轻松地进行数组访问/排序,但是如果需要,您可以重新编制索引:

$ratesData = array_values($ratesData);

答案 2 :(得分:0)

另一个好的解决方案

    $uniqueRates = [];

    foreach ($ratesData as $rateData) {
        $key = $rateData['id'];
        if (!\array_key_exists($key, $uniqueRates) ||
            $rateData['total_amount'] < $uniqueRates[$key]['total_amount']
        ) {
            $uniqueRates[$key] = $rateData;
        }
    }

    return array_values($uniqueRates);