Maurício Giordano
Maurício Giordano

Reputation: 3276

PHP wrap array elements in separate arrays

I have the following array:

$arr = [
    "elem-1" => [ "title" => "1", "desc" = > "" ],
    "elem-2" => [ "title" => "2", "desc" = > "" ],
    "elem-3" => [ "title" => "3", "desc" = > "" ],
    "elem-4" => [ "title" => "4", "desc" = > "" ],
]

First I need to change the value from [ "title" => "1", "desc" = > "" ] to 1 (title's value).

I did this using array_walk:

array_walk($arr, function(&$value, $key) {
    $value = $value["title"];
});

This will replace my value correctly. Our current array now is:

$arr = [
    "elem-1" => "1",
    "elem-2" => "2",
    "elem-3" => "3",
    "elem-4" => "4",
]

Now, I need to transform each element of this array into its own subarray. I have no idea on how to do this without a for loop. This is the desired result:

$arr = [
    [ "elem-1" => "1" ],
    [ "elem-2" => "2" ],
    [ "elem-3" => "3" ],
    [ "elem-4" => "4" ],
]

Upvotes: 1

Views: 2218

Answers (4)

mickmackusa
mickmackusa

Reputation: 48071

It doesn't make much sense to use array_walk() and modify by reference because the final result needs to have completely new keys on both levels. In other words, the output structure is completely different from the input and there are no salvageable/mutable parts. Mopping up the modified array with array_values() only adds to the time complexity cost.

array_map() has to bear a cost to time complexity too because array_keys() must be passed in as an additional parameter.

If you want to use array_walk(), use use() to modify the result array. This will allow you to enjoy the lowest possible time complexity.

More concise than array_walk() and cleaner to read, I would probably use a classic foreach() in my own project.

Codes: (Demo)

$result = [];
array_walk(
    $arr,
    function($row, $key) use(&$result) {
        $result[] = [$key => $row['title']];
    }
);

Or:

$result = [];
foreach ($arr as $key => $row) {
    $result[] = [$key => $row['title']];
}
var_export($result);

Or:

var_export(array_chunk(array_map(fn($row) => $row['title'], $arr), 1, true));

Upvotes: 0

Ajay Kumar
Ajay Kumar

Reputation: 97

You need to use array_map like

$new_arr= array_map(function($key,$val){
return [$key => $val['title']];},array_keys($arr),$arr); 

Upvotes: -2

TommyBs
TommyBs

Reputation: 9648

To offer an alternative solution you could achieve all of this with array_map

 <?php

$arr = [
    "elem-1" => [ "title" => "1", "desc" => "" ],
    "elem-2" => [ "title" => "2", "desc" => "" ],
    "elem-3" => [ "title" => "3", "desc" => "" ],
    "elem-4" => [ "title" => "4", "desc" => "" ],
];



function convertToArray($key,$elem){
   return [$key => $elem['title']];
}

$arr = array_map("convertToArray", array_keys($arr), $arr);
echo '<pre>';
print_r($arr);
echo '</pre>';
?>

outputs

  Array
(
    [0] => Array
        (
            [elem-1] => 1
        )

    [1] => Array
        (
            [elem-2] => 2
        )

    [2] => Array
        (
            [elem-3] => 3
        )

    [3] => Array
        (
            [elem-4] => 4
        )

)

Upvotes: 2

Don&#39;t Panic
Don&#39;t Panic

Reputation: 41820

You can change your array_walk callback to produce that array.

array_walk($arr, function(&$value, $key) {
    $value = [$key => $value["title"]];
});

Run the transformed array through array_values if you need to get rid of the string keys.

$arr = array_values($arr);

Upvotes: 5

Related Questions