6
\$\begingroup\$

Assuming I have 5 arrays, all just indexed arrays, and I would like to combine them, this is the best way I can figure, has anyone found a more efficient solution?

function mymap_arrays() {
    $args = func_get_args();
    $key  = array_shift($args);

    return array_combine($key, $args);
}

$keys   = array('u1', 'u2', 'u3');
$names  = array('Bob', 'Fred', 'Joe');
$emails = array('[email protected]', '[email protected]', '[email protected]');
$ids    = array(1, 2, 3);

$u_keys = array_fill( 0, count($names), array('name', 'email', 'id') );

$users  = array_combine($keys,
            array_map('mymap_arrays', $u_keys, $names, $emails, $ids)
          );

This returns:

Array
(
    [u1] => Array
        (
            [name] => Bob
            [email] => [email protected]
            [id] => 1
        )

    [u2] => Array
        (
            [name] => Fred
            [email] => [email protected]
            [id] => 2
        )

    [u3] => Array
        (
            [name] => Joe
            [email] => [email protected]
            [id] => 3
        )

)

EDIT: After a lot of benchmarking, this is the fastest solution I've come up with

function test_my_new() {
    $args    = func_get_args();
    $keys    = array_shift($args);
    $vkeys   = array_shift($args);
    $results = array();

    foreach($args as $key => $array) {
        $vkey = array_shift($vkeys);

        foreach($array as $akey => $val) {
            $result[ $keys[$akey] ][$vkey] = $val;
        }
    }

    return $result;
}

$keys   = array('u1', 'u2', 'u3');
$names  = array('Bob', 'Fred', 'Joe');
$emails = array('[email protected]', '[email protected]', '[email protected]');
$ids    = array(1,2,3);
$vkeys  = array('name', 'email', 'id');

test_my_new($keys, $vkeys, $names, $emails, $ids);
\$\endgroup\$
4
  • 4
    \$\begingroup\$ Do you have to use arrays? I think using classes to group related data (and behavior) would be a lot nicer. \$\endgroup\$
    – c_maker
    Commented Jul 1, 2011 at 23:16
  • \$\begingroup\$ Why would you even receive the data as such? \$\endgroup\$
    – phant0m
    Commented Jul 11, 2011 at 22:04
  • \$\begingroup\$ sorry for the delay, @c_maker & @phant0m this data is part of an api, I have no control over the format of the data, it actually comes in as delimited strings that I explode into arrays, I edited my question with my latest attempt \$\endgroup\$
    – Trey
    Commented Jul 12, 2011 at 19:54
  • \$\begingroup\$ I have to agree with @c_maker. I would really look at taking the input from the api and feeding it in to classes. At the end of the day, do you really need this code to perform the faster, or to be more easily read and maintained? \$\endgroup\$ Commented Dec 9, 2011 at 13:51

1 Answer 1

2
\$\begingroup\$

I would suggest the following:

function combine_keys_with_arrays($keys, $arrays) {
    $results = array();

    foreach ($arrays as $subKey => $arr)
    {
       foreach ($keys as $index => $key)
       {
           $results[$key][$subKey] = $arr[$index];    
       }
    }

    return $results;
}

$keys    = array('u1', 'u2', 'u3');
$names   = array('Bob', 'Fred', 'Joe');
$emails  = array('[email protected]', '[email protected]', '[email protected]');
$ids     = array(1,2,3);

combine_keys_with_arrays($keys, array('name'  => $names,
                                      'email' => $emails,
                                      'id'    => $ids));

The second parameter to the function can be built as you need it. It avoids array shifting and variable arguments, but I think it should be pretty fast.

\$\endgroup\$

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.