10

What's the easiest way to convert

$a = array(
    array("id" => 1, "name" => "a1"),
    array("id" => 2, "name" => "a2")
);

to

$b = array(
    "a1" => array("id" => 1, "name" => "a1"),
    "a2" => array("id" => 2, "name" => "a2")
);

I was expecting PHP have some functional programming facilities to do something like:

$b = map($a, function($item) {
    return $item["name"];
});

But I didn't find one.

user1633272
  • 2,007
  • 5
  • 25
  • 48

6 Answers6

20

You can use PHP array_column() function. For your use case, the second argument should be null to return the full array.

$a = array(
array("id" => 1, "name" => "a1"),
array("id" => 2, "name" => "a2")
);

$b = array_column($a, null, 'name');

and print_r($b) will result in

Array
(
[a1] => Array
    (
        [id] => 1
        [name] => a1
    )

[a2] => Array
    (
        [id] => 2
        [name] => a2
    )

)
frz3993
  • 1,595
  • 11
  • 13
7

The only solution I see is to loop through the array and create a new array manually.

For example, like this:

$new_array = [];
foreach ($array as $value) 
    $new_array[$value['name']] = $value;
Jerodev
  • 32,252
  • 11
  • 87
  • 108
  • Thanks, I might be influenced by other languages too much. The problem is very common, but I didn't find a built-in solution for it. Yours is the easiest way I could think as well so far. – user1633272 Mar 07 '17 at 14:35
  • Glad I could help. It might also be good to check if `$value['name']` exists otherwise the code might crash in certain situations. – Jerodev Mar 07 '17 at 14:38
  • OK, they are basically objects loaded from one table of database. – user1633272 Mar 07 '17 at 14:40
1

The accepted answer is close, but "close" only counts with hand grenades.

($unique is an indexed array)

$sub_key = 'country';
$new_array = [];
foreach ($unique as $value) {
  $new_array[] = [$sub_key => $value];
}
sea26.2
  • 376
  • 1
  • 5
  • 23
1

You can simply do this

$input = [
    ["id" => 1, "name" => "a1"],
    ["id" => 2, "name" => "a2"]
];

$result = array_merge(
    ...array_map(
        fn($item) => [$item['name'] => $item],
        $input
    )
);
  • 2
    Adding some explanation to your code would make this answer more helpful. Explaining how it improves on the one-line answer given almost 5 years ago would also be a good idea. – miken32 Dec 20 '21 at 22:55
0

Poor me need to implement this in PHP 5.2, and I do not want to use for loop

here's my implementation:

        function getField($x) { return $x['name']; }
        $ids = array_map('getField', $result);
        $result = array_combine($ids, $result);

See if maybe this helps anybody lol

Ng Sek Long
  • 4,233
  • 2
  • 31
  • 38
0

How about:

$a = array(
    array('a' => 'a0', 'b' => 'b0', 'c' => 'c0'),
    array('a' => 'a1', 'b' => 'b1', 'c' => 'c1'),
    array('a' => 'a2', 'b' => 'b2', 'c' => 'c2'),
    );
print_r($a);
print_r(array_combine(array_column($a, 'a'), $a));

Where 'a' is the column to use as the associative index.

This leaves the column that becomes the index in the array.

array_column (PHP 5 >= 5.5.0, PHP 7)

array_combine (PHP 5, PHP 7)

Lummo
  • 99
  • 7