phparraysmultidimensional-arraygrouping

Group rows of a 2d array based on multiple columns


Here my array:

Array (
    [0] => Array (
        [NDC_Id] => 56
        [NDC_Date] => 2017-04-14
        [NDC_Type] => Night
        [NDC_Item] => Night
        [NDC_Rate] => 95.00
        [NDC_Quantity] => 1
        [NDC_Taxes] => 0
        [NDC_TaxesName] => 0
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
    [1] => Array (
        [NDC_Id] => 58
        [NDC_Date] => 2017-04-14
        [NDC_Type] => Item
        [NDC_Item] => Petit déjeuner
        [NDC_Rate] => 16.00
        [NDC_Quantity] => 2
        [NDC_Taxes] => 5.000,9.975
        [NDC_TaxesName] => TPS,TVQ
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
    [2] => Array (
        [NDC_Id] => 59
        [NDC_Date] => 2017-04-14
        [NDC_Type] => Item
        [NDC_Item] => Lit pour bébé
        [NDC_Rate] => 10.00
        [NDC_Quantity] => 1
        [NDC_Taxes] => 5.000,9.975
        [NDC_TaxesName] => TPS,TVQ
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
    [3] => Array (
        [NDC_Id] => 57
        [NDC_Date] => 2017-04-15
        [NDC_Type] => Night
        [NDC_Item] => Night
        [NDC_Rate] => 95.00
        [NDC_Quantity] => 1
        [NDC_Taxes] => 0
        [NDC_TaxesName] => 0
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
    [4] => Array (
        [NDC_Id] => 60
        [NDC_Date] => 2017-04-15
        [NDC_Type] => Item
        [NDC_Item] => Petit déjeuner
        [NDC_Rate] => 16.00
        [NDC_Quantity] => 2
        [NDC_Taxes] => 5.000,9.975
        [NDC_TaxesName] => TPS,TVQ
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
    [5] => Array (
        [NDC_Id] => 61
        [NDC_Date] => 2017-04-15
        [NDC_Type] => Item
        [NDC_Item] => Lit pour bébé
        [NDC_Rate] => 10.00
        [NDC_Quantity] => 1
        [NDC_Taxes] => 5.000,9.975
        [NDC_TaxesName] => TPS,TVQ
        [NDC_Provenance] => Room
        [NDC_ProvenanceRoomId] => 0
        [NDC_Status] => NotCharged
    )
)

I'm trying to group the element when some values are equals and the date the same.

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

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

Problem is the Petit déjeuner and the Night are grouped but not the Lit pour bébé item.

Just before this line $result = array_values($result); I have a strange key name for Lit pour bébé. I have [Item0.69717400 1494009685] and it's not the same key name for both Lit pour bébé. Perhaps it's the problem ?


To reply to Sahil Gulati, the expected result should be the following:

Array (
    [0] => Array (
        [NDCId] => 56,57
        [NDCDate] => 2017-04-14,2017-04-15
        [NDCType] => Night
        [NDCItem] => Night
        [NDCRate] => 95.00
        [NDCQuantity] => 1
        [NDCTaxes] => 0
        [NDCTaxesName] => 0
        [NDCProvenance] => Room
        [NDCProvenanceRoomId] => 0
        [NDCStatus] => NotCharged
    )
    [1] => Array (
        [NDCId] => 58,60
        [NDCDate] => 2017-04-14,2017-04-15
        [NDCType] => Item
        [NDCItem] => Petit déjeuner
        [NDCRate] => 16.00
        [NDCQuantity] => 2
        [NDCTaxes] => 9.975,5.000
        [NDCTaxesName] => TVQ,TPS
        [NDCProvenance] => Room
        [NDCProvenanceRoomId] => 0
        [NDCStatus] => NotCharged
    )
    [2] => Array (
        [NDCId] => 59
        [NDCDate] => 2017-04-14,2017-04-15
        [NDCType] => Item
        [NDCItem] => Lit pour bébé
        [NDCRate] => 10.00
        [NDCQuantity] => 1
        [NDCTaxes] => 9.975,5.000
        [NDCTaxesName] => TVQ,TPS
        [NDCProvenance] => Room
        [NDCProvenanceRoomId] => 0
        [NDCStatus] => NotCharged
    )
)

Solution

  • Here i am using simple foreach to gather and group items

    Try this code snippet here

    ini_set('display_errors', 1);
    $string = '
    {  
        "0"  : {  
            "NDC_Id"  :"56",
            "NDC_Date"  :"2017-04-14",
            "NDC_Type"  :"Night",
            "NDC_Item"  :"Night",
            "NDC_Rate"  :"95.00",
            "NDC_Quantity"  :"1",
            "NDC_Taxes"  :"0",
            "NDC_TaxesName"  :"0",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"},
        "1"  : {  
            "NDC_Id"  :"58",
            "NDC_Date"  :"2017-04-14",
            "NDC_Type"  :"Item",
            "NDC_Item"  :"Petit déjeuner",
            "NDC_Rate"  :"16.00",
            "NDC_Quantity"  :"2",
            "NDC_Taxes"  :"5.000,9.975",
            "NDC_TaxesName"  :"TPS,TVQ",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"},
        "2"  : {  
            "NDC_Id"  :"59",
            "NDC_Date"  :"2017-04-14",
            "NDC_Type"  :"Item",
            "NDC_Item"  :"Lit pour bébé",
            "NDC_Rate"  :"10.00",
            "NDC_Quantity"  :"1",
            "NDC_Taxes"  :"5.000,9.975",
            "NDC_TaxesName"  :"TPS,TVQ",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"},
        "3"  : {  
            "NDC_Id"  :"57",
            "NDC_Date"  :"2017-04-15",
            "NDC_Type"  :"Night",
            "NDC_Item"  :"Night",
            "NDC_Rate"  :"95.00",
            "NDC_Quantity"  :"1",
            "NDC_Taxes"  :"0",
            "NDC_TaxesName"  :"0",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"},
        "4"  : {  
            "NDC_Id"  :"60",
            "NDC_Date"  :"2017-04-15",
            "NDC_Type"  :"Item",
            "NDC_Item"  :"Petit déjeuner",
            "NDC_Rate"  :"16.00",
            "NDC_Quantity"  :"2",
            "NDC_Taxes"  :"5.000,9.975",
            "NDC_TaxesName"  :"TPS,TVQ",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"},
        "5"  : {  
            "NDC_Id"  :"61",
            "NDC_Date"  :"2017-04-15",
            "NDC_Type"  :"Item",
            "NDC_Item"  :"Lit pour bébé",
            "NDC_Rate"  :"10.00",
            "NDC_Quantity"  :"1",
            "NDC_Taxes"  :"5.000,9.975",
            "NDC_TaxesName"  :"TPS,TVQ",
            "NDC_Provenance"  :"Room",
            "NDC_ProvenanceRoomId"  :"0",
            "NDC_Status"  :"NotCharged"}}';
    $result = array();
    $array = json_decode($string, true);
    foreach ($array as $item)
    {
        if(!isset($result[$item["NDC_Type"].$item["NDC_Item"]]))
        {
            $result[$item["NDC_Type"].$item["NDC_Item"]]=$item;
        }
        else
        {
            $result[$item["NDC_Type"].$item["NDC_Item"]]["NDC_Date"].=",".$item["NDC_Date"];
            $result[$item["NDC_Type"].$item["NDC_Item"]]["NDC_Id"].=",".$item["NDC_Id"];
        }
    }
    print_r(array_values($result));
    

    Output:

    Array
    (
        [0] => Array
            (
                [NDC_Id] => 56,57
                [NDC_Date] => 2017-04-14,2017-04-15
                [NDC_Type] => Night
                [NDC_Item] => Night
                [NDC_Rate] => 95.00
                [NDC_Quantity] => 1
                [NDC_Taxes] => 0
                [NDC_TaxesName] => 0
                [NDC_Provenance] => Room
                [NDC_ProvenanceRoomId] => 0
                [NDC_Status] => NotCharged
            )
    
        [1] => Array
            (
                [NDC_Id] => 58,60
                [NDC_Date] => 2017-04-14,2017-04-15
                [NDC_Type] => Item
                [NDC_Item] => Petit déjeuner
                [NDC_Rate] => 16.00
                [NDC_Quantity] => 2
                [NDC_Taxes] => 5.000,9.975
                [NDC_TaxesName] => TPS,TVQ
                [NDC_Provenance] => Room
                [NDC_ProvenanceRoomId] => 0
                [NDC_Status] => NotCharged
            )
    
        [2] => Array
            (
                [NDC_Id] => 59,61
                [NDC_Date] => 2017-04-14,2017-04-15
                [NDC_Type] => Item
                [NDC_Item] => Lit pour bébé
                [NDC_Rate] => 10.00
                [NDC_Quantity] => 1
                [NDC_Taxes] => 5.000,9.975
                [NDC_TaxesName] => TPS,TVQ
                [NDC_Provenance] => Room
                [NDC_ProvenanceRoomId] => 0
                [NDC_Status] => NotCharged
            )
    
    )
    

    Solution 2: Try this code snippet here

    Change your code from this:

    $k = $item['NDC_Type'];
    

    This:

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