2014-02-10 2 views
0

Что я пытаюсь сделать: Сравните значение массива, которое является объектом с другими объектами в массиве. Если определенные свойства объекта в игле (объект, который я сравниваю с другими объектами) соответствуют тем же свойствам в другом объекте в стоге сена, затем слияние определенных свойств от иглы к совпадающему объекту в стоге сена и снятие иголки.Как сравнить и удалить объект в массиве с другими объектами в массиве?

Некоторые псевдо-код:

<?php 
$haystack = array($obj1, $obj2, $obj3); 
if(!empty($haystack)){ 
    for($x=0;$x<count($haystack);$x++){ 
     if($haystack[$x]->prop1 == $haystack[$x+1]->prop1 && $haystack[$x]->prop2 == $haystack[$x+1]->prop2){ 
      $haystack[$x]->combined1 = $haystack[$x]->prop1.','.$haystack[$x+1]->prop1; 
      unset($haystack[$x+1]); 
     } 
    } 
} 
?> 
+0

Можете ли вы реализовать метод 'toArray' в объектах? Если нет, '(array) $ obj' передать их в массив, а затем использовать' array_intersect', чтобы определить разницу, если любой –

+0

@EliasVanOotegem. Проведение сравнения относительно просто. Я думаю, что проблема связана с отключением следующего элемента в массиве, который в настоящее время выполняется итерацией. Получив $ array [$ x + 1], он переместил итератор вперед и испортил сравнение (я думаю). – Chad

+0

Изменить 'unset ($ haystack [$ x + 1])' to 'unset ($ haystack [++ $ x])', это увеличивает '$ i', пропуская индекс unset на следующей итерации цикла –

ответ

1

Расширение чуть на мой комментарий:

Вы должны изменить unset($haystack[$x+1]); к unset($haystack[++$x]);
Если, скажем, индексы 0 и 1 равны, ваш текущий цикл unsets $haystack[1], сохраняя значение $i на 0, цикл затем продолжает увеличивать $i с 1 (до 1 в этом случае) и выполняет сравнение с $haystack[1] , который только что был отменен.
На самом деле приращение $i означает, что, в конце цикла $i будет равен 1, а не 0. Это будет увеличиваться еще раз, и в следующий раз, то цикл будет сравнивать индексы 2 и 3.

for ($x = 0, $max = count($haystack);$x <$max;++$x) 
{ 
    if ($haystack[$x] == $haystack[$x+1]) 
    {//only increment if you unset! 
     unset($haystack[++$x]); 
    } 
} 

Это должно сделать трюк. Если вы хотите сравнить все элементы данного массива, то вам придется гнездо две петли:

for ($x = 0, $max = count($haystack);$x <$max;++$x, $max =count($haystack)) 
{//re-assign $max after inner loop completes, and reset keys 
    for ($j = $x+1;$j<$max;++$j) 
    { 
     if ($haystack[$x] == $haystack[$j]) 
     {//No need to increment again 
      unset($haystack[$j]); 
     } 
    } 
    $haystack = array_values($haystack);//this resets the keys 
} 

Это должно решить вашу проблему

+0

Это много ближе, чем я был ранее. Кажется, все еще есть одна ошибка. Если у меня есть $ haystack из 4 объектов, 3 из которых имеют одинаковые prop1 и prop2, я все равно заканчиваю массив из трех объектов вместо двух. – Chad

+0

Вам нужно будет использовать вложенный цикл для этого, тогда ... если вы хотите сравнить все элементы массива ... Я обновил свой ответ –

0

Решение

 for($x=0;$x<count($haystack);$x++){ 
      for($y=0;$y<=count($haystack);$y++){ 
       if($haystack[$x]->prop1 == $haystack[$y]->prop1 && $haystack[$x]->prop2 == $haystack[$y]->prop2){ 
        if($haystack[$x]->prop3 == $haystack[$y]->prop3){ 
         continue; 
        }else{ 
         $haystack[$x]->prop1 .= $haystack[$y]->prop1; 
         unset($haystack[$y]); 
        } 
       } 
      } 
     } 

В ретроспективе , это была довольно простая проблема для решения. Проблема заключалась в том, чтобы мысленно держать итераторы прямо и знать, сколько было нужно. Чтобы это работало без копирования массива или с использованием посредника, вам просто нужно создать экземпляр двух итераторов для одновременного итерации массива, чтобы вы могли сравнить $ array [0-n] до $ array [0-n] вместо сравнения $ array [0-n] до $ arrayCopy [0-n].

Смежные вопросы