2011-09-11 152 views
2

我有對象的兩個數組,循環和比較對象

他們是相同的,除了一個有多個項目,

,使他們看起來像

Array [arrayA] 
(
    [0] => stdClass Object 
     (
      [id] => 2 
      [name] => interest 1 
      [description] => interest one 
     ) 

    [1] => stdClass Object 
     (
      [id] => 4 
      [name] => interest 3 
      [description] => interest three 
     ) 

) 



Array [arrayB] 
(
    [0] => stdClass Object 
     (
      [id] => 1 
      [name] => all 
      [description] => everything 
     ) 

    [1] => stdClass Object 
     (
      [id] => 2 
      [name] => interest 1 
      [description] => interest one 
     ) 

    [2] => stdClass Object 
     (
      [id] => 4 
      [name] => interest 3 
      [description] => interest three 
     ) 

    [3] => stdClass Object 
     (
      [id] => 5 
      [name] => interest 4 
      [description] => interest four 
     ) 

) 

現在我想做的是,如果找到對象arrayA(可能比較ID?),則在arrayB之上循環,然後在arrayB上設置[checked] => true其他集合[checked] = false

這樣做最簡單的方法是什麼?

我曾經想過做也許

foreach($arrayB as &$obj){ 
    $obj->checked = false; 
    foreach($arrayA as $obja){ 
     if($obja->id == $obj->id){ 
      $obj->checked = true; 
      break; 
     } 
     if($obja->id > $obj->id) //thanks to De3pTh0ught 
      break; 
    } 
} 

,但必須有一個更有效的方法?

回答

1

你可以添加一個檢查來削減無用的迭代。如果您知道數組中的對象ID總是按遞增順序排列,那麼可以包含以下條件:如果$ obja的ID大於$ obj的ID,則返回break $ arrayA的foreach循環,因爲這意味着$ obj永遠不會找到一場比賽。

0

這可以用這個可怕黑客來完成:

$p = print_r($arrayA, true); 
foreach($arrayB as &$o) $o->checked =substr_count($p, "[id] => {$o->id}\n") == 1; 
+0

小心解釋這一點? (雖然我不認爲我會在生產中使用這個...... waaay難以理解......) – Hailwood

+0

啊。我知道了。但哇... – Hailwood

+0

在第1行,我們得到一個字符串,就像你在你的問題中所擁有的一樣。在第2行中,我們遍歷$ arrayB中的id,並且爲每一個我們編寫一個像[[id] => 1'這樣的子字符串,並檢查$ p中是否有它的兩個實例,我們將這個比較的結果賦給'$ o - > checked' –

0

經過一番思考如何低效substr_count可能是 - 認爲它的內部實現的;(2行!)它不能很有效率 - 我想出了一個稍微不同的方法:

$b = print_r($arrayA, true); 
foreach($arrayB as &$o) 
    $o->checked = strpos($b, "[id] => {$o->id}" . PHP_EOL, 60) !== false;