2
\$\begingroup\$

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.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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]
        )

)
\$\endgroup\$
2
  • \$\begingroup\$ I like that, I like that very much... You may want to swap '@value' and '@name' in the array_column function. Since I want the key as the identifier, and the value in the value place. \$\endgroup\$
    – Sam
    May 10, 2018 at 20:58
  • 1
    \$\begingroup\$ Oh yes, you're right @Samuel. I'll update the answer. Thank you! \$\endgroup\$
    – Syscall
    May 10, 2018 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.