4

I have a multidimensional indexed array. Each element is an associative array with an id column which is unique between elements (its value never repeats within the array).

[indexed] =>Array
(
    [0] => Array
        (
            [id] => john
            [name] => John
            [age] => 29
        ),

    [1] => Array
        (
            [id] => peter
            [name] => Peter
            [age] => 30
        ),

    [2] => Array
        (
            [id] => harry
            [name] => Harry
            [age] => 19
        )
)

My goal is to convert this array into a multidimensional associative array, indexed by id values.

[indexed] =>Array
(
    [john] => Array
        (
            [id] => john
            [name] => John
            [age] => 29
        ),

    [peter] => Array
        (
            [id] => peter
            [name] => Peter
            [age] => 30
        ),

    [harry] => Array
        (
            [id] => harry
            [name] => Harry
            [age] => 19
        )
)

My best attempt so far is to loop over array elements and manually create the final array.

$associative = array();
foreach($indexed as $key=>$val) $associative[$val['id']] = $val;

I think it's not the most elegant solution. Is it possible to obtain the same result with built-in (more efficient) functions?

2
  • I think in PHP there is no inbuilt function which overwrites Key by a particular value in an array. If array count is not huge then this solution is OK. Otherwise use XML or JSON which is fast in processing Commented Oct 25, 2016 at 12:13
  • @MangeshSathe that claim is incorrect. See my answer. Commented Sep 7, 2018 at 9:07

2 Answers 2

9

The truth is php DOES offer a single, native function that allows you to replace the outer indexes with the values of a single column. The "magic" is in the 2nd parameter which tells php not to touch the subarray values when assigning the new keys.

Code: (Demo)

$indexed = [
    ['id' => 'john', 'name' => 'John', 'age' => 29],
    ['id' => 'peter', 'name' => 'Peter', 'age' => 30],
    ['id' => 'harry', 'name' => 'Harry', 'age' => 19],
];

var_export(array_column($indexed, null, 'id'));

Output:

array (
  'john' => 
  array (
    'id' => 'john',
    'name' => 'John',
    'age' => 29,
  ),
  'peter' => 
  array (
    'id' => 'peter',
    'name' => 'Peter',
    'age' => 30,
  ),
  'harry' => 
  array (
    'id' => 'harry',
    'name' => 'Harry',
    'age' => 19,
  ),
)

This even works on an array of objects. The end result is an array of objects with new, associative first-level keys. (Demo)

$indexed = [
    (object)['id' => 'john', 'name' => 'John', 'age' => 29],
    (object)['id' => 'peter', 'name' => 'Peter', 'age' => 30],
    (object)['id' => 'harry', 'name' => 'Harry', 'age' => 19],
];

var_export(array_column($indexed, null, 'id'));

Output:

array (
  'john' => 
  (object) array(
     'id' => 'john',
     'name' => 'John',
     'age' => 29,
  ),
  'peter' => 
  (object) array(
     'id' => 'peter',
     'name' => 'Peter',
     'age' => 30,
  ),
  'harry' => 
  (object) array(
     'id' => 'harry',
     'name' => 'Harry',
     'age' => 19,
  ),
)
Sign up to request clarification or add additional context in comments.

Comments

1

Here is another way of doing it (assuming $arr is your original array):

$associative = array_combine(array_map(function($item) { return $item['id']; }, $arr), $arr);

But I think using a foreach is still shorter and more readable compare to this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.