1

I have the following two arrays:

userStatus
---------------
Array
(
    [0] => Array
        (      
            [Username] => cynthia@test.net
            [Status] => Active
        )

    [1] => Array
        (           
            [Username] => mary@test.net
            [Status] => Terminated
        )

    [2] => Array
        (           
            [Username] => steve@test.net
            [Status] => OnVacation
        )
)

users
------
Array
(
    [0] => steve@test.net
    [1] => mark@test.net
    [2] => cynthia@test.net
)

I want to write a snippet that brings up an array of all userStatus entries that do not match on Username field in the users Array.

How can I do this? I don't seem to find an efficient and fast way to do this in PHP.

Thanks

hakre
  • 193,403
  • 52
  • 435
  • 836
Jake
  • 25,479
  • 31
  • 107
  • 168
  • 2
    You'll have to use at least one loop for this. What have you tried? – Yoshi Mar 21 '12 at 23:44
  • @Yoshi [No loops!](http://codepad.viper-7.com/hl3RiS) (Yes, I know, no-one likes a smart-arse) – cmbuckley Mar 22 '12 at 00:07
  • 1
    @cbuckley that's just a well hidden loop ;). but a nice one nonetheless! should add it as an answer – Yoshi Mar 22 '12 at 00:10
  • @Yoshi true :-) I've added it as an answer but in fairness I didn't believe it to be the clearest of solutions, hence my originally placing it in the comments. – cmbuckley Mar 22 '12 at 00:17
  • possible duplicate of [Compare two arrays and list common entries](http://stackoverflow.com/questions/9782435/compare-two-arrays-and-list-common-entries) - Please do not duplicate questions because you're not confident with the answers so far. Improve the question instead or start to chat. – hakre Jul 01 '12 at 10:56

3 Answers3

2
$result = array();
foreach($userStatus as $value) {
     if(!in_array($value['Username'], $users) {
        $result[] = $value;
     }
}

print_r($result);
safarov
  • 7,793
  • 2
  • 36
  • 52
0

With your current arrays there is no logical way to avoid traversing $users for every $userStatus which would use exponential time O(n^2) and could get out of hand.

If instead you could convert $users to a hash (perhaps array_flip) then you could do it in linear time O(n).

$usersHash = array_flip($users);

foreach ($userStatuses as $status) {
    if (!array_key_exists($status['username'], $usersHash)) {
        // do something with the user
    }
}

Check out this related post for some information regarding time complexity of common PHP functions.

Community
  • 1
  • 1
Billy
  • 1,212
  • 10
  • 10
0

This answer was originally me being facetious, and I would suggest that safarov's answer is the clearest, but here's a solution with a custom callback to array_diff:

$userStatus = array(
    array('Username' => 'cynthia@test.net', 'Status' => 'Active'),
    array('Username' => 'mary@test.net',    'Status' => 'Terminated'),
    array('Username' => 'steve@test.net',   'Status' => 'OnVacation'),
);

$users = array(
    'cynthia@test.net',
);

var_dump(array_udiff($userStatus, $users, function($status, $user) {
    return $status['Username'] !== $user;
}));
cmbuckley
  • 40,217
  • 9
  • 77
  • 91