在PHP中检查相同类的实例的值

I've got a class: Game which has values.

I've got two arrays with Game instances. Now I need to compare those two arrays for identical values in the game instance.

The game class has the attributes: homeId visitingId

Now I need to check for identical values in both arrays (they are large, 100+ game instances)

What I do is:

foreach ($games1 as $game1) {
 foreach ($games2 as $game2) {
   if ( ($game1->getHomeId() == $game2->getHomeId()) && ($game1->getVisitingId() == $game2->getVisitingId())) {
     //Games are the same
   }
 }
}

This takes ages, is there a way to do it quicker?

I've got it running but it's dirty I think.

At first I store the instances in a hashtable, the hash is made out of the visitorId and the homeId.

Then I create an hash of the visitorId and homeId of the other games array.

Then I retrieve the instance by using $table[$hash].

The arrays I used to have aren't the same in lenght, so this works. I don't know if it's too dirty to post here but it works :P

foreach($pGames as $pGame) {
    $hash = $pGame->getHomeId() . '-' . $pGame->getVisitingId();
        $table[$hash] = $pGame; 
}
foreach($games as $game) {
    $hash = $game->getHomeId() . '-' . $game->getVisitingId();
    $pGame = $table[$hash];
    if($pGame instanceof Game) {
        //use the instance
    }
}

You're doing a lot of redundant calculations. Use a for loop instead of a foreach loop and start at where you left off, instead of at the beginning:

$games1_count = count($games1);
$games2_count = count($games2);

for($i=0; $i < $games1_count; $i++) {
    $game1 = $games1[$i];
    for($j=$i; $j < $games2_count; $j++) {
        $game2 = $games2[$j];
        if (($game1->getHomeId == $game2->getHomeId()) && $game1->getVisitingId == $game2->getVisitingId()) {
            //Games are the same
        }
    }
}

This should provide a pretty significant speed boost. It won't decrease the order of the problem, but it will cut your calculations in half.

EDIT

You should also look into some sort of indexing. When you populate $game1, for instance, create an array that stores the games by value:

$game_index = array(
    "home_id"=array(
        "id1"=>$reference_to_game_with_id1,
        "id2"=>$reference_to_game_with_id2
    ),
    "visiting_id"=array(
        "id1"=>$reference_to_game_with_visiting_id1,
        "id2"=>$reference_to_game_with_visiting_id2
    )
);

How about using the array_diff function in some way which compares two arrays. http://php.net/manual/en/function.array-diff.php

Your current solution has complexity of O(n*n). it is possible to get it down to O(nlogn). For this you'll have to sort both arrays and then compare them. I would do something like:

$t1=array();
foreach ($games1 as $key=>$game1) {
  $t1[$key]=$game1->getHomeId;
}
asort($t1);
$t2=array();
foreach ($games2 as $key=>$game2) {
  $t2[$key]=$game2->getHomeId();
}
asort($t2);
$el1=each($t1);
$el2=each($t2);
do{
  if ($el1['value']<$el2['value'])
    $el1=each($t1);
  elseif ($el1['value']>$el2['value'])
    $el2=each($t2);
  elseif($games1[$el1['key']]->getVisitingId == $games2[$el2['key']]->getVisitingId())
    //game are the same

}while($el1 !== false && $el2 !== false)

this produces considerable overhead, so on small amount of data it will work slower. However the more data are in the arrays, the more efficient this algorithm will be.