1

I'm trying to construct an array where there only strings and the array would look like this key->key->value

To explain it I attached two screenshots below.

I start with this: enter image description here

After my code below I'm 90% there, yet there is an array in value on the third level instead of simple value.

enter image description here

Here is some code:

    $theme = ThemeHandler::with('sections.settings')->find($activeTheme);
    $themeSettings = $theme->sections;
    $themeSettings = collect($themeSettings->toArray());

    // dd($themeSettings);

    $themeSections = [];
    foreach ($themeSettings as $key => $value) {
        $settings = collect($value['settings']);
        $settings = $settings->mapToGroups(function ($item) {
            return [$item['key'] => $item['value']];
        });
        $themeSections[$value['key']] = $settings->toArray(); 
    }
    dd($themeSections);

I would like to end up with this structure

key->key->value

and not

key->key->single_element_array->value

I'm not sure how I end up with an array at the bottom level when I do this

return [$item['key'] => $item['value']];

inside the mapToGroups, which is a function found here: https://laravel.com/docs/5.8/collections#method-maptogroups

Maybe I misunderstand how mapToGroups work. Anybody has an idea how to get key->key->value structure output?

niko craft
  • 2,893
  • 5
  • 38
  • 67
  • 1
    `$item['value']` is most likely an array at that point, which is why its returning an array. If its always going to be a single item array you can do `return [$item['key'] => ( ( is_array( $item['value'] ) ) ? $item['value'][0] : $item['value'] )];` – Second2None Apr 18 '19 at 22:10
  • I know my data, $item['value'] is a simple value. Somehow mapToGroup turns it into an array and puts the value there as the only item. – niko craft Apr 18 '19 at 22:12
  • 1
    This may help https://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential – zod Apr 18 '19 at 22:26

1 Answers1

2

Use mapWithKeys() instead of mapToGroups().

You're getting an array instead of the simple value you expect because the value is a group, albeit a group with only one member.

mapToGroups() groups all the values with the same key, but mapWithKeys() will assign a single value to each key.

You can see in the examples in the collection documentation, mapToGroups() produces a result like this:

[
    'Sales' => ['John Doe', 'Jane Doe'],
    'Marketing' => ['Johnny Doe'],
]

And mapWithKeys() result is like this:

[
    'john@example.com' => 'John',
    'jane@example.com' => 'Jane',
]
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • hmm I will try that, you are right value somehow turns into array because mapToGroups works that way? – niko craft Apr 18 '19 at 22:37
  • I got it working, two nested mapWithKeys did the trick, there are no extra arrays inserted now between levels. You literally saved me a few hours of headache! :) Much obliged! I also got rid of the foreach, two mapWithKeys are more elegant. – niko craft Apr 18 '19 at 22:44