如何过滤数组以仅包含每个ID的最新项?

时间:2016-08-25 13:10:37

标签: php arrays multidimensional-array

我有一个如下数组:

Array
(
    [0] => Array
        (
            [clearing] => 160000
            [paydate] => 2016-08-03
            [latecharge] => 900
        )
    [1] => Array
        (
            [clearing] => 160000
            [paydate] => 2016-08-04
            [latecharge] => 950
        )
    [2] => Array
        (
            [clearing] => 160001
            [paydate] => 2016-08-05
            [latecharge] => 850
        )
)

我正在尝试保留每个清算的最新paydate并删除阵列的其余部分。

例如,对于清除160000,最新的paydate是2016-08-04,而对于160001,最新的paydate是2016-08-05,所以我的结果数组应如下所示:

Array
(
    [1] => Array
        (
            [clearing] => 160000
            [paydate] => 2016-08-04
            [latecharge] => 950
        )
    [2] => Array
        (
            [clearing] => 160001
            [paydate] => 2016-08-05
            [latecharge] => 850
        )
)

我该怎么做?

2 个答案:

答案 0 :(得分:3)

通过'清除'键循环遍历阵列和分组。每次到达结果数组中未设置“清除”的地方时,将其设置为当前实例,或者如果已设置,则在当前实例较新时替换它。

foreach ($clearings as $clearing) {
    $id = $clearing['clearing'];
    if (!isset($latest[$id]) || $latest[$id]['paydate'] < $clearing['paydate']) {
        $latest[$id] = $clearing;
    }
}

来自@jeroen的评论很有用。例如,如果您(或将来的读者)从数据库获取此数组,则修改查询并在数据库中执行此操作的效率最高。这个概念被称为groupwise maximum,并且有一些很好的答案,有几种不同的方法可以在this question上得到它。

答案 1 :(得分:0)

创建一个遍历数组的函数。

function clearOldPaydates($array)
{
    $cleaned = array();
    foreach($array as $item)
    {
        // if it's the first item of this date we keep it
        // if there is already an item with this date we only overwrite it if it's older
        if(!isset($cleaned[$item['paydate']])
            || strtotime($item['paydate']] > $cleaned[$item['paydate'])
        {
            $cleaned[$item['paydate']] = $item;
        }
    }
    // we return the array with numeric keys
    return array_values($cleaned);
}