2

I'm trying to apply custom keys to a collection in laravel.

The best way that I found was using functions like transform or mapWithKeys.

$result = $collection->map(function ($item) {
    return [
        'custom_key_name_1' => $item[0],
        'custom_key_name_2' => $item[1],
        'custom_key_name_3' => $item[2],
    ];
});

I was hoping to find something like:

$keys = ['custom_key_name_1', 'custom_key_name_2', 'custom_key_name_3'];
result = $collection->withKeys($keys);

Do you know any other way to do that with a less verbose code?

I'm working in a legacy Laravel 5.5 project.

Input Example

$collection = collect([
    [ 'first', 'second', 'third' ],
    [ '1', '2', '3' ],
    [ '1st', '2nd', '3rd' ],
]);

Expected Output

[
  [
    'custom_key_name_1' => 'first',
    'custom_key_name_2' => 'second',
    'custom_key_name_3' => 'third',
  ],
  [
    'custom_key_name_1' => '1',
    'custom_key_name_2' => '2',
    'custom_key_name_3' => '3',
  ],
  [
    'custom_key_name_1' => '1st',
    'custom_key_name_2' => '2nd',
    'custom_key_name_3' => '3rd',
  ],
]
miken32
  • 42,008
  • 16
  • 111
  • 154
FabianoLothor
  • 2,752
  • 4
  • 25
  • 39
  • There is no other way, what is the issue with that code? Is it that overbosed for you? – matiaslauriti Feb 17 '23 at 23:51
  • @matiaslauriti yeah, it seems unnecessarily verbose for me. Anyway, thanks for clarify that, I thought that there was a less-code way. – FabianoLothor Feb 18 '23 at 00:35
  • No worries, but belive me that that code is not overbosed at all. It may not be the best one, but it is pretty good. Maybe you would like to create a macro for a Collection, so you create your own `withKeys` (following your example) and end up with the same stuff. Read [this](https://laravel.com/docs/5.5/collections#extending-collections) – matiaslauriti Feb 18 '23 at 02:27
  • What do you not like? That you have to do `$item[0], $item[1], ...` ? – Chin Leung Feb 18 '23 at 03:45

1 Answers1

1

Since you're working with a collection of arrays, you can use PHP's array_combine() method to put the keys and values together:

$collection = collect([
    [ 'first', 'second', 'third' ],
    [ '1', '2', '3' ],
    [ '1st', '2nd', '3rd' ],
]);
$keys = collect(['custom_key_name_1', 'custom_key_name_2', 'custom_key_name_3']);

$result = $collection->map(fn ($v) => $keys->combine($v));

dump($result);

Result:

Illuminate\Support\Collection^ {#5189
  #items: array:3 [
    0 => array:3 [
      "custom_key_name_1" => "first"
      "custom_key_name_2" => "second"
      "custom_key_name_3" => "third"
    ]
    1 => array:3 [
      "custom_key_name_1" => "1"
      "custom_key_name_2" => "2"
      "custom_key_name_3" => "3"
    ]
    2 => array:3 [
      "custom_key_name_1" => "1st"
      "custom_key_name_2" => "2nd"
      "custom_key_name_3" => "3rd"
    ]
  ]
  #escapeWhenCastingToString: false
}

The important caveat being that, per the documentation, "a ValueError is thrown if the number of elements in keys and values does not match."

FabianoLothor
  • 2,752
  • 4
  • 25
  • 39
miken32
  • 42,008
  • 16
  • 111
  • 154
  • I'm marking that as right answer because I don't think we'll find anything better nowadays. The combine option reduces the boiler plate, but it isn't optimal yet. Initial code calls just `map` while the answer calls `map+combine`, anyway, thank you for the help. – FabianoLothor Feb 24 '23 at 23:42