I am still attempting to learn how to best handle arrays and iterate their values transforming them into the correct formats that are needed for my database/API.
So I have this array:
$arr = [
0 => [
'field' => [
0 => [
'@name' => 'first_name',
'@value' => 'Jack'
],
1 => [
'@name' => 'last_name',
'@value' => 'Lew'
],
2 => [
'@name' => 'email',
'@value' => '[email protected]'
]
]
]
];
And I need it to look like this:
[0] => Array
(
[first_name] => Jack
[last_name] => Lew
[email] => [email protected]
)
To get to this I have taken the same approach I usually take:
for( $i = 0; $i < count($arr); $i++ ) {
foreach($arr[$i] as $k => $v) {
print_r($k . ': \r\n');
if( is_array($v) ) {
foreach($v as $key => $val) {
$new[$i][$val['@name']] = $val['@value'];
}
}
}
}
The problem I having here is, I believe there has to be a better way to achieve the same results without being three levels deep of loops, since they are slower and just harder to debug altogether.
I would appreciate any insights on how I can make this code better in both readability and performance.
1 Answer 1
If you know that the key field
exists, you could use array_map()
to apply a function on each row. This function could use array_column()
to transform a column as keys, and another as values:
$arr = [
[
'field' => [
['@name' => 'first_name', '@value' => 'Jack'],
['@name' => 'last_name', '@value' => 'Lew'],
['@name' => 'email', '@value' => '[email protected]']
]
],
[
'field' => [
['@name' => 'first_name', '@value' => 'John'],
['@name' => 'last_name', '@value' => 'Doe'],
['@name' => 'email', '@value' => '[email protected]']
]
]
];
$data = array_map(function($item) {
return array_column($item['field'], '@value', '@name');
}, $arr) ;
print_r($data);
Output:
Array
(
[0] => Array
(
[first_name] => Jack
[last_name] => Lew
[email] => [email protected]
)
[1] => Array
(
[first_name] => John
[last_name] => Dow
[email] => [email protected]
)
)
-
\$\begingroup\$ I like that, I like that very much... You may want to swap
'@value'
and'@name'
in thearray_column
function. Since I want the key as the identifier, and the value in the value place. \$\endgroup\$sam– sam2018年05月10日 20:58:53 +00:00Commented May 10, 2018 at 20:58 -
1\$\begingroup\$ Oh yes, you're right @Samuel. I'll update the answer. Thank you! \$\endgroup\$Syscall– Syscall2018年05月10日 21:05:00 +00:00Commented May 10, 2018 at 21:05