使用php从数组中分组元素

时间:2017-06-16 15:08:36

标签: php arrays foreach

我有这个数组。

Array
(
    [0] => Array
        (
            [NDC_Id] => 118
            [NDC_Date] => 2017-04-11
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 90.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Room
            [NDC_ProvenanceRoomId] => 0
            [NDC_Status] => charged
        )

    [1] => Array
        (
            [NDC_Id] => 119
            [NDC_Date] => 2017-04-12
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 90.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Room
            [NDC_ProvenanceRoomId] => 0
            [NDC_Status] => charged
        )

    [2] => Array
        (
            [NDC_Id] => 98
            [NDC_Date] => 2017-04-19
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 95.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Transfert
            [NDC_ProvenanceRoomId] => 10
            [NDC_Status] => charged
        )

    [3] => Array
        (
            [NDC_Id] => 99
            [NDC_Date] => 2017-04-20
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 95.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Transfert
            [NDC_ProvenanceRoomId] => 10
            [NDC_Status] => charged
        )

    [4] => Array
        (
            [NDC_Id] => 100
            [NDC_Date] => 2017-04-21
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 95.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Transfert
            [NDC_ProvenanceRoomId] => 10
            [NDC_Status] => charged
        )

    [5] => Array
        (
            [NDC_Id] => 117
            [NDC_Date] => 2017-04-22
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 95.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Transfert
            [NDC_ProvenanceRoomId] => 10
            [NDC_Status] => charged
        )
)

当某些数据元素相等(比率,项目,数量......)且日期是连续的时,以下脚本会将元素分组。

在其他情况下,这些项目不会被分组。

// We group the elements in to a new array
$result = [];

foreach ($array as $item) {
    $k = $item['NDC_Type'].$item['NDC_Item'];

    if (!isset($result[$k])) {
        $result[$k] = $item;
    } elseif (
        ($i = $result[$k]) && 
        $item['NDC_Rate'] === $i['NDC_Rate'] && 
        $item['NDC_Item'] === $i['NDC_Item'] && 
        $item['NDC_Quantity'] === $i['NDC_Quantity'] &&
        $item['NDC_Taxes'] === $i['NDC_Taxes'] && 
        $item['NDC_TaxesName'] === $i['NDC_TaxesName'] && 
        $item['NDC_Status']=== $i['NDC_Status'] && 
        $item['NDC_Provenance'] === $i['NDC_Provenance'] && 
        $item['NDC_ProvenanceRoomId'] === $i['NDC_ProvenanceRoomId']
    ) {

        $result[$k]['NDC_Id'] .= ','. $item['NDC_Id'];

        $current_dates = explode(',', $result[$k]['NDC_Date']);
        $last_date = end($current_dates);
        if(date('Y-m-d', strtotime("{$last_date} +1 day")) === $item['NDC_Date']) {
            $result[$k]['NDC_Date'] .= ','. $item['NDC_Date'];
        } else {
            $result[$k. microtime()] = $item;
        }
    } else {
        $result[$k. microtime()] = $item;
    }
}

$result = array_values($result);

如果我只有一个组,则脚本会根据需要对项目进行分组。

如果我要组合两个或更多组,则会制作第一组,但不会制作另一组。

如何解决我的问题?

预期结果将是:

Array
(
    [0] => Array
        (
            [NDC_Id] => 118,119
            [NDC_Date] => 2017-04-11,2017-04-12
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 90.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Room
            [NDC_ProvenanceRoomId] => 0
            [NDC_Status] => charged
        )

    [1] => Array
        (
            [NDC_Id] => 98,99,100,117
            [NDC_Date] => 2017-04-19,2017-04-20,2017-04-21,2017-04-22
            [NDC_Type] => Night
            [NDC_Item] => Night
            [NDC_Rate] => 95.00
            [NDC_Quantity] => 1
            [NDC_Taxes] => 0
            [NDC_TaxesName] => 0
            [NDC_Provenance] => Transfert
            [NDC_ProvenanceRoomId] => 10
            [NDC_Status] => charged
        )
)

1 个答案:

答案 0 :(得分:0)

问题

看来确定唯一的字段来自这一行:

$k = $item['NDC_Type'].$item['NDC_Item'];

因为数组中的所有5个元素在这些字段中看起来都具有相同的值,所以它会尝试连接这些字段。但是, NDC_Rate 在最后三个子阵列中是不同的。

解决方案

一种解决方案是将费率附加到$ k:

$k = $item['NDC_Type'].$item['NDC_Item'].$item['NDC_Rate'];

这样,元素将按 Type Item Rate 进行分组。

this playground example中看到它。

正如Jeff所提到的,更简单的解决方案是将项目分组到数据库层中(例如,如果使用SQL,则使用 GROUP BY 子句 - 对于各种引擎(如{ {3}},MySQLsql server等。)