skip to Main Content

I need to group the data from my 2d array into an associative array of associative arrays where d values are the first level keys, and the s values will become the second level keys, and the i values should be (potentially comma-separated) second level values in their respective group.

Input:

$array = [
    ["d" => "7 Apr 2024", "s" => "pm", "i" => "el"],
    ["d" => "8 Apr 2024", "s" => "am", "i" => "mn"],
    ["d" => "12 Apr 2024", "s" => "pm", "i" => "mr"],
    ["d" => "12 Apr 2024", "s" => "am", "i" => "mr"],
    ["d" => "12 Apr 2024", "s" => "am", "i" => "da"],
    ["d" => "13 Apr 2024", "s" => "pm", "i" => "li"],
    ["d" => "14 Apr 2024", "s" => "am", "i" => "li"],
    ["d" => "15 Apr 2024", "s" => "mid", "i" => "nd"],
    ["d" => "15 Apr 2024", "s" => "pm", "i" => "da"]
]

Desired result:

[
    "7 Apr 2024" => ["pm" => "el"],
    "8 Apr 2024" => ["am" => "mn"],
    "12 Apr 2024" => ["am" => "mr,da", "pm" => "mr"],
    "13 Apr 2024" => ["pm" => "li"],
    "14 Apr 2024" => ["am" => "li"],
    "15 Apr 2024" => ["pm" => "da", "mid" => "nd"]
]

I have tried every version of every foreach loop using if statements, using while statements, and temporary arrays. I am having difficulty combining the second level values when the date is the same.

2

Answers


  1. You need to use array_walk on the input array to create the output.

    $output = [];
    
    array_walk($array, function ($item) use (&$output) {
        if (array_key_exists($item["d"], $output) && array_key_exists($item["s"],$output[$item["d"]])) {
            $output[$item["d"]][$item["s"]] .= "," . $item["i"];
        } else {
            $output[$item["d"]][$item["s"]] = $item["i"];
        }
    });
    
    print_r($output);
    
    Login or Signup to reply.
  2. Use the two grouping columns as the first and second levels of your array. If the combination of first two values are not represented in the result array, save it, otherwise append a comma and the new value.

    Code: (Demo)

    $result = [];
    foreach ($array as ['d' => $d, 's' => $s, 'i' => $i]) {
        if (!isset($result[$d][$s])) {
            $result[$d][$s] = $i;
        } else {
            $result[$d][$s] .= ',' . $i;
        }
    }
    var_export($result);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search