Home > Software engineering >  How to convert a Single Array into a multidimensional array in PHP using letters
How to convert a Single Array into a multidimensional array in PHP using letters

Time:10-11

I need to generate a multidimensional array based on a "map" of letters

my array :

$list = [
  0 => [
    'name' => 'blah',
    'path' => 'A'
  ],
  1 => [
    'name' => 'blah',
    'path' => 'AA'
  ],
  2 => [
    'name' => 'blah',
    'path' => 'AB'
  ],
  3 => [
    'name' => 'blah',
    'path' => 'B'
  ],
  4 => [
    'name' => 'blah',
    'path' => 'BA'
  ],
  5 => [
    'name' => 'blah',
    'path' => 'BAA'
  ],
];

but I need this:

$list = [
  0 => [
    'name' => 'blah',
    'path' => 'A',
    'childs' => [
      0 => [
        'name' => 'blah',
        'path' => 'AA'
      ],
      1 => [
        'name' => 'blah',
        'path' => 'AB'
      ],
    ]
  ],
  3 => [
    'name' => 'blah',
    'path' => 'B',
    'childs' => [
      0 => [
        'name' => 'blah',
        'path' => 'BA',
        'childs' => [
          0 => [
            'name' => 'blah',
            'path' => 'BAA'
          ],
        ]
      ],
    ]
  ],
];

I'm going to need this array to be in a way that is easy to manipulate, but I'm not able to use the "&" in a foreach so that I can generate an array at least close to what I put above.

sorry if i asked the question incorrectly... my english is bad and it's my first time here

CodePudding user response:

Because there weren't much clues on the question on how to actually do the desired grouping. I'll assume, based on the provided output sample, that the grouping will be based on the first letter found in the values where the key is path. The task will basically be solved using array_reduce() built-in function:

Iteratively reduce the array to a single value using a callback function. Source: php.net

To maintain a performant solution, we'll index the resulting array based on the letters we found (the letters we'll group using them). Like so we will iterate over the $list array only once.

The trick here is to decide what to do at every iteration of the array_reduce function:

  • When it's the first time we encounter a new letter, let's call that letter $letter, then we will construct an array (based on your output sample) where $letter is the key.
  • Otherwise, if we have already the letter in the resulting array we will simply merge the children of the resulting array of the $letter key.

Using the letters as keys will drastically improve the solution's performance because we can simply say $result[$letter] and this will immediately return the array found on the $letter key (O(1)).

To illustrate, here's a code sample that should get the job done:

$list = [
    ['name' => 'blah', 'path' => 'A'],
    ['name' => 'blah', 'path' => 'AA'],
    ['name' => 'blah', 'path' => 'AB'],
    ['name' => 'blah', 'path' => 'B'],
    ['name' => 'blah', 'path' => 'BA'],
    ['name' => 'blah', 'path' => 'BAA'],
];

$result = array_reduce($list, function ($a, $c) {
    $l = substr($c['path'], 0, 1);
    isset($a[$l])
        ? $a[$l]['children'][] = $c
        : $a[$l] = [
        'name' => $c['name'],
        'path' => $c['path'],
        'children' => []
    ];
    return $a;
}, []);

The $result array will have the letters as keys, if you need to remove those letters and use numerical keys, you may call

And I have made a live demo too.

  • Related