Milorad
Milorad

Reputation: 162

Combine columnar values in each row of a 2d array to form dynamically keyed elements

I have this array:

$params = [
    ['name'  => 'xxx', 'value' => 'yyy'],
    ['name'  => 'uuu', 'value' => 'vvv']
];

and I want to achieve this:

$params = [
    ['xxx' => 'yyy'],
    ['uuu' => 'vvv']
];

I can do it this way:

foreach ($params as &$param) {
    $param[$param['name']] = $param['value'];
    unset($param['name']);
    unset($param['value']);
    unset($param);
}

But I am wondering if this could be done on more elegant way?

Upvotes: 1

Views: 151

Answers (7)

mickmackusa
mickmackusa

Reputation: 48071

All of the following snippets will produce the same desired result from the provided input array. Demo

Make a new array with a body-less loop.

$result = [];
foreach ($params as ['name' => $k, 'value' => $result[][$k]]);
var_export($result);

Make a new array using iterated chunk&combining.

var_export(
    array_map(
        fn($row) => array_combine(...array_chunk($row, 1)),
        $params
    )
);

Make a new array using iterated hardcoded declarations.

var_export(
    array_map(
        fn($row) => [$row['name'] => $row['value']],
        $params
    )
);

Make a new array by reducing the columns to a flat associative array, then re-expand to a 2d array.

var_export(
    array_chunk(
        array_column($params, 'value', 'name'),
        1,
        true
    )
);

Modify the original array by reference without using first level keys.

foreach ($params as &$row) {
    $row = [$row['name'] => $row['value']];
}
var_export($params);

Upvotes: 0

Meloman
Meloman

Reputation: 3722

Try this :

foreach ($params as $key => $sub_array) {

    // unset original array data
    unset($params[$key]);

    // construct the new values
    $params[$key][$sub_array['name']] = $sub_array['value'];
}

EDIT:

Another approach more elegant is the following :

foreach($params as $k=>$s){
    $params[$k]=array($s['name']=>$s['value']);
}

Upvotes: 0

Anant Ram Verma
Anant Ram Verma

Reputation: 1

Please try this:

foreach ($params as $k => $v)
{
    $nary[$v[name]] = $v[value];
}

$params = $nary;

Upvotes: -3

The fourth bird
The fourth bird

Reputation: 163632

To make your current code a little bit more elegant, you could pass multiple arguments to unset

foreach ($params as &$param) {
    $param[$param['name']] = $param['value'];
    unset($param['name'], $param['value'], $param);
}

Upvotes: 0

Eddie
Eddie

Reputation: 26854

You can use array_map to reiterate the array.

$params = [
  [
    'name'  => "xxx",
    'value' => "yyy"
  ],
  [
    'name'  => "uuu",
    'value' => "vvv"
  ]
];

$params = array_map(function($o){
    return [ $o['name'] => $o['value'] ];
}, $params);


echo "<pre>";
print_r( $params );
echo "</pre>";

This will result to:

Array
(
    [0] => Array
        (
            [xxx] => yyy
        )

    [1] => Array
        (
            [uuu] => vvv
        )

)

Doc: array_map()

Upvotes: 1

wayneOS
wayneOS

Reputation: 1425

This is a bit shorter. By not using foreach you can directly replace the elements.

for ($i = 0; $i < count ($params); $i++)
    $params[$i] = array ($params[$i]['name'] => $params[$i]['value']);

Upvotes: 0

deceze
deceze

Reputation: 522606

This calls for an array mapping of values:

$params = array_map(function ($i) { return [$i['name'] => $i['value']]; }, $params);

Upvotes: 6

Related Questions