0

I have this array data:

array:3 [
  0 => array:5 [
    "menu_id" => 7
    "menu_name" => "Kasagbutan Meals"
    "menu_price" => "100.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  1 => array:5 [
    "menu_id" => 7
    "menu_name" => "Kasagbutan Meals"
    "menu_price" => "100.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  2 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
]

When I ran it with array_unique(), the data becomes like this:

array:2 [
  0 => array:5 [
    "menu_id" => 7
    "menu_name" => "Kasagbutan Meals"
    "menu_price" => "100.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
  2 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
]

How can I add the qty before it reduces the array? I want to add the qty of the removed array item. So basically, the ideal array result should be like this:

array:2 [
  0 => array:5 [
    "menu_id" => 7
    "menu_name" => "Kasagbutan Meals"
    "menu_price" => "100.00"
    "qty" => "2" ----> THIS BECOMES 2 BECAUSE THE OTHER ITEM HAS A QTY OF 1.
    "special_instructions" => ""
  ]
  2 => array:5 [
    "menu_id" => 6
    "menu_name" => "Coke"
    "menu_price" => "50.00"
    "qty" => "1"
    "special_instructions" => ""
  ]
]
5
  • Are you obtaining that data from a relational/nosql database? Commented Jul 6, 2020 at 2:16
  • What makes one entry equal to another? Just the menu_id property or does it take into account other properties too? Commented Jul 6, 2020 at 2:17
  • @Phil - If they have the same values in the following keys: - menu_id - menu_name - menu_price - special_instructions So basically all EXCEPT qty Commented Jul 6, 2020 at 2:21
  • So you're saying entries can have the same menu_id but different menu_name, menu_price, etc? What's the point in having a field named "id" if it doesn't identify the record? Commented Jul 6, 2020 at 2:23
  • @Phil - Actually, No. Ideally if they have the same menu_id it will also have the same menu_name, menu_price, etc.. I am including menu_id because I am returning this data in the frontend and my JS code is doing some logic in this also. Commented Jul 6, 2020 at 2:26

1 Answer 1

2

array_unique() is simply a reduce operation. What you want is a slightly more complex one so use array_reduce()

$exclude = array_flip(['qty']); // list of properties to exclude when creating a hash

$totals = array_reduce($arr, function($totals, $item) use ($exclude) {
    $id = array_diff_key($item, $exclude);
    ksort($id); // sort by key to always get the same order
    $hash = crc32(json_encode($id));
    if (array_key_exists($hash, $totals)) {
        $totals[$hash]['qty'] += $item['qty'];
    } else {
        $totals[$hash] = $item;
    }
    return $totals;
}, []);

This builds up a new array keyed by a hash of identifying values (everything except for qty) that, upon finding an entry it already knows about, increases the qty.

I've gone with a CRC32 hash of the JSON encoded string for speed. You can use just about any hashing / serialization combo though.

Demo ~ https://3v4l.org/YDsfc

Special nods to the following posts:

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for, but I tried adding a different value in the special_instructions but it combined it with the others that doesnt have a special_instructions value. This is before it ran through your code: pastebin.com/hG8C35Q0 noticed that the other has a value in special_instructions, this is AFTER your code: pastebin.com/sCu76Que Ideal output should be like this: pastebin.com/Gk5ttWEr

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.