Rob1982
Rob1982

Reputation: 63

Combine or merge array based on values

I have an array which gives me the order delivery date and an array of what items were on that order.

(
[0] => Array
    (
        [0] => 14 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

[1] => Array
    (
        [0] => 14 May, 2021
        [1] => Array
            (
                [0] => Cookies & Cream Brownies
            )

    )

[2] => Array
    (
        [0] => 14 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

[3] => Array
    (
        [0] => 29 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

[4] => Array
    (
        [0] => 13 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

[5] => Array
    (
        [0] => 13 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

[6] => Array
    (
        [0] => 14 May, 2021
        [1] => Array
            (
                [0] => Bestsellers Brownie Box
            )

    )

What I need to do is to sort of merge this, so we end up with an array that is more like this:

[0] => Array
    (
        [0] => 14 May, 2021
        [1] => Array
            (
                [0] => 3 x Bestsellers Brownie Box
                [1] => 1 x Cookies & Cream Brownies
            )

    )

[1] => Array
    (
        [0] => 29 May, 2021
        [1] => Array
            (
                [0] => 1 x Bestsellers Brownie Box
            )

    )

[2] => Array
    (
        [0] => 13 May, 2021
        [1] => Array
            (
                [0] => 2 x Bestsellers Brownie Box
            )

    )

So it brings together everything that is due out for delivery on a specific day. I hope that makes sense. The plan here is to create a calendar view so that at a glance, my client can see how many items they have out for delivery on a certain day.

I just can't work out how to combine/merge/join these arrays in such a way. I have some ideas but I just think they might get quite cumbersome, and someone here is bound to have some good methods of doing this. Thanks in advance!

Upvotes: 0

Views: 62

Answers (1)

arkascha
arkascha

Reputation: 42915

Something like that would do what you ask:

<?php
$input = [
[
  "14 May, 2021",
  [ "Bestsellers Brownie Box" ] ],
[
  "14 May, 2021",
  [ "Cookies & Cream Brownies" ] ], 
  [
    "14 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "29 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "13 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "13 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "14 May, 2021",
    [ "Bestsellers Brownie Box" ] ]
];

$output = [];
array_walk($input, function($order) use (&$output) {
  $date = $order[0];
  $items = $order[1];
  
  if (!array_key_exists($date, $output)) {
    $output[$date] = [];
  }
  
  foreach ($items as $item) {
    if (array_key_exists($item, $output[$date])) {
      $output[$date][$item] += 1;
    } else {
      $output[$date][$item] = 1;
    }
  }
});

print_r($output);

The output obviously is:

Array
(
    [14 May, 2021] => Array
        (
            [Bestsellers Brownie Box] => 3
            [Cookies & Cream Brownies] => 1
        )
    [29 May, 2021] => Array
        (
            [Bestsellers Brownie Box] => 1
        )
    [13 May, 2021] => Array
        (
            [Bestsellers Brownie Box] => 2
        )
)

A variant to create exactly the format you suggested would be that:

<?php
$input = [
[
  "14 May, 2021",
  [ "Bestsellers Brownie Box" ] ],
[
  "14 May, 2021",
  [ "Cookies & Cream Brownies" ] ], 
  [
    "14 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "29 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "13 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "13 May, 2021",
    [ "Bestsellers Brownie Box" ] ], 
  [
    "14 May, 2021",
    [ "Bestsellers Brownie Box" ] ]
];

$output = [];
array_walk($input, function($order) use (&$output) {
  $date = $order[0];
  $items = $order[1];
  
  if (!array_key_exists($date, $output)) {
    $output[$date] = [$date, []];
  }
  
  foreach ($items as $item) {
    if (array_key_exists($item, $output[$date][1])) {
      $output[$date][1][$item] += 1;
    } else {
      $output[$date][1][$item] = 1;
    }
  }
});
$output = array_values($output);

print_r($output);

The that output:

Array
(
    [0] => Array
        (
            [0] => 14 May, 2021
            [1] => Array
                (
                    [Bestsellers Brownie Box] => 3
                    [Cookies & Cream Brownies] => 1
                )

        )
    [1] => Array
        (
            [0] => 29 May, 2021
            [1] => Array
                (
                    [Bestsellers Brownie Box] => 1
                )

        )
    [2] => Array
        (
            [0] => 13 May, 2021
            [1] => Array
                (
                    [Bestsellers Brownie Box] => 2
                )

        )
)

Upvotes: 1

Related Questions