Assign column value in a 2d array as the first level key

106 Views Asked by At

Let's say I have the following array

[
        {
            "id": "16",
            "name": "dog",
        },
        {
            "id": "17",
            "name": "cat",
        },
        {
            "id": "18",
            "name": "mouse",
        }
]

I want to use a specific attribute, id as the key for the array. I could do this:

$someArray = [
    ["id" => "16", "name" => "dog"],
    ["id" => "17", "name" => "cat"],
    ["id" => "18", "name" => "mouse"]
];


$newArray = [];
foreach ($someArray as $currItem)
{
    $newArray[$currItem["id"]] = $currItem;
}

Then I would have this (the desired outcome)

{
    "16": {
        "id": "16",
        "name": "dog"
    },
    "17": {
        "id": "17",
        "name": "cat"
    },
    "18": {
        "id": "18",
        "name": "mouse"
    }
}

My question is: is there a better way to do this? Do I really have to loop through every item just to redefine my array ever so slightly?

2

There are 2 best solutions below

0
On

I seem to have found a solution using information from Rizier123's answer on another question.

As far as I can tell array_column() is only going to give me an array of ids, so I need to use it with array_combine() and array_values().

$someArray = [
    ["id" => "16", "name" => "a"],
    ["id" => "17", "name" => "b"],
    ["id" => "18", "name" => "c"]
];

$newArray =  array_combine(array_column($someArray, "id"), $someArray);
10
On

You beat me to the answer but I might contribute a little anyway...

I'm not sure where your original array is coming from, but if you are decoding JSON, then you can provide a second param to force objects to be converted to associative arrays

$contents = trim(file_get_contents("/home/jaith/foo/foo.json"));
$arr = json_decode($contents, TRUE); // note the second parameter
$v = array_combine(array_column($arr, "id"), $arr); 
var_dump($v);

EDIT: If you can tolerate your output array having objects, this might also work:

$contents = trim(file_get_contents("/home/jaith/foo/foo.json"));
$arr = json_decode($contents);
$v = array_combine(
        array_column(
                array_map(
                        function($item) { return (array)$item; },
                        $arr 
                ),
                "id"
        ),
        $arr
);
var_dump($v);

Keep in mind though that performance could become a concern for very very large arrays. This is doing a lot of array munging.