Jithin Jose
Jithin Jose

Reputation: 1821

Extract array from multidimentional array wrt key

I have an array

$users    = array();

$users[0]['id']=1;
$users[0]['name']="user1";

$users[1]['id']=2;
$users[1]['name']="user2";

$users[2]['id']=3;
$users[2]['name']="user3";

And i need to extract id's into another array $ids; such that

$ids[0]=1;
$ids[1]=2;
$ids[2]=3;

I know one way to do it...

$ids    = array();
foreach($users as $user){
   $ids[]  = $user['id'];
}

But

1.is it is the best way to doit? 2.is it possible to do it without loops. 3.is it is the fastest way....?

Upvotes: 1

Views: 146

Answers (2)

Kerem
Kerem

Reputation: 11576

  • I think the best way is your way as programmer (but if you in team then the best way is the team way).
  • I think I'll go relying on built in PHP function (except some functions) for performance issues forever (cos I think the PHP peer work hard as needed to improve it).
  • I think it's possible to do it without loops.
$users = array();
$users[0]['id'] = 100;
$users[1]['id'] = 101;
$users[2]['id'] = 102;

$ids = array();
array_walk_recursive($users, function($val, $key) use(&$ids){
    if ($key == 'id') $ids[] = $val;
});

print_r($ids);


Array
(
    [0] => 100
    [1] => 101
    [2] => 102
)

Upvotes: 0

periklis
periklis

Reputation: 10188

All the comments above address the question very well, but since noone has actually posted any actual answer, here's some additional info (to justify my answering it):

  • Is it the best way to do it?

Probably, but it is certainly the cleaner and most readable way to do it

  • is it possible to do it without loops?

Yes, but as people have said, it's only a trick, as loops will be used in the background.

  • is it is the fastest way?

Now this calls for some investigation. I have recreated a similar array as yours, using 100000 entries:

for ($i=0;$i<100000;$i++) {
    $users[] = array('id' => rand(),
            'name' => 'default');
}

And ran a few tests using different cases:

1.Plain old for loop (the one you have used yourself):

$ids=array();
$t = microtime(true);
foreach ($users as $key => $value) {
    $ids[] = $value['id'];
} 
echo microtime(true)-$t;

This required 0.085'' on average

2.Using array_walk():

$t = microtime(true);
array_walk($users, create_function('$v,$k,&$ids', '$ids[0][] = $v["id"];'), array(&$ids));
echo microtime(true)-$t;

This required on average 0.22'' (the same when using $GLOBALS['ids'] instead of this "reference" hack)

3.Using splFixedArray: This iterator is supposed to be faster than plain arrays. Indeed, the code above requires 0.075'' on average:

$users = new SplFixedArray(100000);
for ($i=0;$i<100000;$i++) {
    $users[$i] = array('id' => rand(),
            'name' => 'default');
}
$ids=array();
$t = microtime(true);
foreach ($users as $key => $value) {
    $ids[$key] = $value['id'];
}
echo microtime(true)-$t;

While the code below, where we use splFixedArray for both arrays, performed even faster, around 0.062'':

$users = new SplFixedArray(100000);
for ($i=0;$i<100000;$i++) {
    $users[$i] = array('id' => rand(),
            'name' => 'default');
}
$ids=new SplFixedArray(100000);
$t = microtime(true);
foreach ($users as $key => $value) {
    $ids[$key] = $value['id'];
}
echo microtime(true)-$t;

So, the bottom line is that no, it's not the fastest way, but it's the best if you take into account all 3 parameters you posed in your initial question

Upvotes: 2

Related Questions