Group data in an associative multidimensional array and remove duplicates in subarrays

41 Views Asked by At

I have an array like this:

$array = [
    [
        2 => 'kategorie_01',
        'tags' => [
            1 => 'tag_01',
            2 => 'tag_02',
        ],
    ],
    [
        3 => 'kategorie_02',
        'tags' => [
            2 => 'tag_02',
        ],
    ],
    [
        1 => 'Default',
        'tags' => [
            1 => 'tag_01',
            2 => 'tag_02',
        ],
    ],
    [
        2 => 'kategorie_01',
        'tags' => [
            2 => 'tag_02',
            3 => 'tag_03',
        ],
    ],
];

I would like to change the above array to the following array. All duplication of the categories should be eliminated. The first category (2 => kategorie_01) receives all tags of the deleted categorie (2 => kategorie_01). Duplicated tags should also be deleted in this category.

[
    [
        2 => 'kategorie_01',
        'tags' => [
            1 => 'tag_01',
            2 => 'tag_02',
            3 => 'tag_03',
        ],
    ],
    [
        3 => 'kategorie_02',
        'tags' => [
            2 => 'tag_02',
        ],
    ],
    [
        1 => 'Default',
        'tags' => [
            1 => 'tag_01',
            2 => 'tag_02',
        ],
    ],
];
1

There are 1 best solutions below

0
mickmackusa On

Assuming that category values always come before tags values AND the keys of each tag can be used to determine tag value uniqueness, you can push references into a result array when a category is first encountered, then append unique data on subsequent encounters.

Code: (Demo)

$result = [];
foreach ($array as $set) {
    foreach ($set as $k => $v) {
        if ($k !== 'tags') {
            $cat = $v;
            if (!isset($ref[$v])) {
                $ref[$v] = $set;
                $result[] = &$ref[$v];
            }
        } else {
            $ref[$cat]['tags'] += $v;
        }
    }
}
var_export($result);

Output:

array (
  0 => 
  array (
    2 => 'kategorie_01',
    'tags' => 
    array (
      1 => 'tag_01',
      2 => 'tag_02',
      3 => 'tag_03',
    ),
  ),
  1 => 
  array (
    3 => 'kategorie_02',
    'tags' => 
    array (
      2 => 'tag_02',
    ),
  ),
  2 => 
  array (
    1 => 'Default',
    'tags' => 
    array (
      1 => 'tag_01',
      2 => 'tag_02',
    ),
  ),
)