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' => 'jack@gmail.com'
            ]
        ]
    ]
];

And I need it to look like this:

[0] => Array
    (
        [first_name] => Jack
        [last_name] => Lew
        [email] => jack@gmail.com
    )

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
\$\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' => 'jack@gmail.com']
        ]
    ],
    [
        'field' => [
            ['@name' => 'first_name', '@value' => 'John'],
            ['@name' => 'last_name', '@value' => 'Doe'],
            ['@name' => 'email', '@value' => 'John@gmail.com']
        ]
    ]
];

$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] => jack@gmail.com
        )

    [1] => Array
        (
            [first_name] => John
            [last_name] => Dow
            [email] => John@gmail.com
        )

)
\$\endgroup\$
  • \$\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\$ – Samuel May 10 '18 at 20:58
  • 1
    \$\begingroup\$ Oh yes, you're right @Samuel. I'll update the answer. Thank you! \$\endgroup\$ – Syscall May 10 '18 at 21:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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