I have an object as below,
{"metaData":[{"name":"a"},{"name":"b"}],"rows":[[1,2],[3,4],[5,6]]}
I would like to change it to
[["a"=>1,"b"=>2],["a"=>4,"b"=>5],["a"=>5,"b"=>6]]
Is there any faster one liner that can convert this without going thru a loop in Laravel ?
CodePudding user response:
You can get the keys with array_column
, then map array_combine
over the rows.
$keys = array_column($object->metaData, 'name');
$result = array_map(fn($row) => array_combine($keys, $row), $object->rows);
You could make it a one-liner like this, but it's more difficult to read, and it will call array_column
for every row instead of just once.
$result = array_map(fn($row) => array_combine(array_column($object->metaData, 'name'), $row), $object->rows);
You need to be sure that each row is the same size as the metadata array or array_combine
will fail. Based on the appearance of your object, it looks like this would probably always be true, but it's important to note.
CodePudding user response:
BUT. This is almost a one liner :)
$str = '{"metaData":[{"name":"a"},{"name":"b"}],"rows":[[1,2],[3,4],[5,6]]}';
$obj = json_decode($str);
$obj->rows = array_map( function ($a) {return ['a'=>$a[0], 'b'=>$a[1]];} , $obj->rows);
print_r($obj);
echo json_encode($obj);
RESULT
stdClass Object
(
[metaData] => Array
(
[0] => stdClass Object
([name] => a)
[1] => stdClass Object
([name] => b)
)
[rows] => Array
(
[0] => Array
([a] => 1,[b] => 2)
[1] => Array
([a] => 3,[b] => 4)
[2] => Array
( [a] => 5,[b] => 6)
)
)
{"metaData":[{"name":"a"},{"name":"b"}],"rows":[{"a":1,"b":2},{"a":3,"b":4},{"a":5,"b":6}]}
UPDATE, Using the names form the metaData for the array indexes. Not a one liner any more, but it was fun rangling it
$str = '{"metaData":[{"name":"ali"},{"name":"bill"}],"rows":[[1,2],[3,4],[5,6]]}';
$obj = json_decode($str);
// get array of names
$names = array_map( function ($a) {return $a->name;}, $obj->metaData);
// use it in the array map to get any number of names
$rows = array_map( function ($a) use($names) {
for( $x=0; $x<count($names); $x ) {
$ret[] = [$names[$x]=>$a[$x]];
}
return $ret;
}
, $obj->rows);
$obj->rows = $rows;
print_r($obj);
echo json_encode($obj);
NEW RESULTS
stdClass Object
(
[metaData] => Array
(
[0] => stdClass Object
(
[name] => ali
)
[1] => stdClass Object
(
[name] => bill
)
)
[rows] => Array
(
[0] => Array
(
[0] => Array
(
[ali] => 1
)
[1] => Array
(
[bill] => 2
)
)
[1] => Array
(
[0] => Array
(
[ali] => 3
)
[1] => Array
(
[bill] => 4
)
)
[2] => Array
(
[0] => Array
(
[ali] => 5
)
[1] => Array
(
[bill] => 6
)
)
)
)
{"metaData":[{"name":"ali"},{"name":"bill"}],"rows":[[{"ali":1},{"bill":2}],[{"ali":3},{"bill":4}],[{"ali":5},{"bill":6}]]}