1

I have this kind of array data:

array:4 [
  0 => array:7 [
    "menu_id" => 1
    "menu_name" => "Cheese Burger"
    "menu_price" => "100.00"
    "modItem" => array:2 [
      0 => array:3 [
        "id" => 62
        "name" => "Regular Coke"
        "price" => "50.00"
      ]
      1 => array:3 [
        "id" => 79
        "name" => "Small Fries"
        "price" => "10.00"
      ]
    ]
    "addOnItem" => array:2 [
      0 => array:3 [
        "id" => 1
        "name" => "Ice Cream"
        "price" => "30.00"
      ]
      1 => array:3 [
        "id" => 49
        "name" => "Tuna Pie"
        "price" => "20.00"
      ]
    ]
    "qty" => "1"
    "special_instructions" => "this is a test special instruction"
  ]
  1 => array:5 [
    "menu_id" => 8
    "menu_name" => "Regular Yum Burger"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  2 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  3 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "2"
    "special_instructions" => ""
  ]
]

As you can see, the Coke is repeating and, i want to combine their qty and output a new array. So the output should be like this:

array:4 [
  0 => array:7 [
    "menu_id" => 1
    "menu_name" => "Cheese Burger"
    "menu_price" => "100.00"
    "modItem" => array:2 [
      0 => array:3 [
        "id" => 62
        "name" => "Regular Coke"
        "price" => "50.00"
      ]
      1 => array:3 [
        "id" => 79
        "name" => "Small Fries"
        "price" => "10.00"
      ]
    ]
    "addOnItem" => array:2 [
      0 => array:3 [
        "id" => 1
        "name" => "Ice Cream"
        "price" => "30.00"
      ]
      1 => array:3 [
        "id" => 49
        "name" => "Tuna Pie"
        "price" => "20.00"
      ]
    ]
    "qty" => "1"
    "special_instructions" => "this is a test special instruction"
  ]
  1 => array:5 [
    "menu_id" => 8
    "menu_name" => "Regular Yum Burger"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  2 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "3"
    "special_instructions" => ""
  ]
]

The qty becomes 3 because I added together their qty key.

Take note that there will be times that the array key will have a modItem and addOnItem key. These will need to be checked too if these are repeating and have existing values with the other keys.

So basically if an array key has the same data within that single array, they will be combined and their quantity will be added up together.

Apologies if i didn't explain this properly as I am having difficulty explaing it, but feel free to leave a question.

Thanks in advance!

3 Answers 3

1

Ideally you'd take care of this issue when constructing the array originally as it's much easier to deal with at that point (by e.g. putting the items in the array with their id as the index and then adding the quantity if the index is already there).

Right now what you can do is something like:

$data = collect($array)
    ->reduce(function ($carry, $item) {
        $existing = $carry->filter(function ($otherItem, $index) use ($item) {
            // All items which are the same except for qty
            return Arr::except($otherItem, 'qty') == Arr::except($item, 'qty');
        });
        if ($existing->isNotEmpty()) {    
             $key = $existing->keys()->first();     
             $value = $existing->first();                
             $value['qty'] += $item['qty']??1;
             $carry->put($key, $value);
        } else {
             $carry->push($item);
        }
        return $carry;
    }, collect())->values();
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, thanks for this. This looks really good and seems to be working. I will test it out with items that has addOnItem and modItem keys. I will get back to you asap!
I tested it further and noticed that it combines the array data even if the special_instruction has a different data in it. This is the original array data before processing it to your code: pastebin.com/QbGHnYZ8. As you can see the other array item has a value in the special_instructions key. This is the array result when processing it with your code: pastebin.com/QkGUEKqJ It combined the array even if the special_instructions key has a value. The correct result should separate the other one and combine those other 2. Thanks again, you're such a big help!
I also noticed that it combined the menu even if they have different modItem and addOnItem data.
Hi, thanks for getting back. For some reason, i am not getting any result. That code returns an empty array. I think it's because of this code: $existing = $carry->filter(function ($otherItem, $index) use ($item) { // All items which are the same except for qty return Arr::except($otherItem, 'qty') == Arr::except($item, 'qty'); });
0

You need to group first then map to sum

$mystuff = collect($yourArray);

$result = $mystuff->groupBy('menu_name')->map(function ($row) {
    return $row->sum('qty');
});

hope this works for you

3 Comments

great let me know :)
Hi, it doesnt work as what i'm expecting. It should still return those array data except the repeating data has been combined and the qty has been add up. The answer of apokryfos is much closer but it combines the array data even if there's a difference on some of the key's value such as the special_instructions.
Yours returned something like this: Illuminate\Support\Collection {#1277 #items: array:2 [ "Cheese Burger" => 1 "eagle cake" => 3 ]
0

Just an important note ,if you have to increment the amount of qty you have to take those value as type int not string because string cannot be incremented and rest is all the output you want.

Array

$data = [
  [
    "menu_id" => 1,
    "menu_name" => "Cheese Burger",
    "menu_price" => "100.00",
    "modItem" => [
      [
        "id" => 62,
        "name" => "Regular Coke",
        "price" => "50.00"
      ],
      [
        "id" => 79,
        "name" => "Small Fries",
        "price" => "10.00"
      ]
    ],
    "addOnItem" => [
      [
        "id" => 1,
        "name" => "Ice Cream",
        "price" => "30.00"
      ],
      [
        "id" => 49,
        "name" => "Tuna Pie",
        "price" => "20.00"
      ]
    ],
    "qty" => 1,
    "special_instructions" => "this is a test special instruction"
  ],
  [
    "menu_id" => 8,
    "menu_name" => "Regular Yum Burger",
    "menu_price" => "50.00",
    "qty" => 1,
    "special_instructions" => ""
  ],
  [
    "menu_id" => 6,
    "menu_name" => "Coke",
    "menu_price" => "50.00",
    "qty" => 1,
    "special_instructions" => ""
  ],
  [
    "menu_id" => 6,
    "menu_name" => "Coke",
    "menu_price" => "50.00",
    "qty" => 2,
    "special_instructions" => ""
  ]
];
for ($i=0; $i < sizeof($data) ; $i++) { 
 if ($data[$i]["menu_name"] == $data[$i + 1]["menu_name"] ) {
 $data[$i]["qty"] += $data[$i + 1]["qty"];
 unset($data[$i + 1]);
 }
}
print_r($data);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.