13

I have the following array :

$array = [
    '2' => ['3' => ['56' => '2'], '6' => ['48' => '2']],
    '4' => ['4' => ['433' => '2', '140' => '2'], '8' => ['421' => '2', '140' => '2']],
    '5' => ['5' => ['88' => '4', '87' => '2']]
];

The following code (flattening) should return it by preserving keys, but it doesnt?

collect($array)->flatten(1);

should give me

[
    '3' => ['56' => '2'],
    '6' => ['48' => '2'],
    '4' => ['433' => '2', '140' => '2'],
    '8' => ['421' => '2', '140' => '2'],
    '5' => ['88' => '4', '87' => '2']
]

However it loses the keys, and just gives array results :/ Am I using it wrong? How should I flatten and preserve keys?

GTMeteor
  • 807
  • 3
  • 9
  • 17
  • 1
    I don't believe `flatten` supports maintaining keys - how would you expect it to work if the keys in a lower level weren't unique? – iainn Dec 11 '17 at 16:26
  • OK, thanks. It makes sense in retrospect why flatten wouldn't keep the keys. – GTMeteor Dec 11 '17 at 18:42

2 Answers2

52

An elegant solution is to use the mapWithKeys method. This will flatten your array and keep the keys:

collect($array)->mapWithKeys(function($a) {
    return $a;
});

The mapWithKeys method iterates through the collection and passes each value to the given callback. The callback should return an associative array containing a single key / value pair

bmagg
  • 906
  • 8
  • 6
2

You can't use flatten() here. I don't have an elegant solution, but I've tested this and it works perfectly for your array:

foreach ($array as $items) {
    foreach ($items as $key => $item) {
        $newArray[$key] = $item;
    }
}

dd($newArray);
Alexey Mezenin
  • 158,981
  • 26
  • 290
  • 279