2012-04-22 2 views
2

У меня есть массив объектов $tab, которые являются «строкой» из таблицы (например, вы можете получить доступ к каждому столбцу через "$tab[$i]->columnname.Php: как вычислить различные между двумя массивами «похожих» объектов?

У меня есть еще один массив объектов $tab_json, что является возвращением вызова AJAX, и что содержит, слишком, «строки» из таблицы (например, вы можете получить доступ к каждому столбцу через "$tab_json[$i]->columnname.

Обе массивы содержат одни и те же colums, но я просто хотел бы, чтобы„угадать“, какие из них в $tabне настоящее время в $tab_json.

Конечно, я знаю array-intersect и array-diff функции, но они, похоже, не работают хорошо при сравнении объектов. Разве я не прав?

Вот пример, который я хотел бы работать, но есть исключение Php:

tab_json = PHP Catchable fatal error: Object of class stdClass could not be converted to string in sample.php on line 112 

Просто скопируйте вставьте его и запустить его в файл (php -f filename.php). Любая идея, как мне это сделать?

<?php 
$tab = array(
    (object)array(
     'id'   => 1, 
     'titre'  => "Anchois", 
     'attributs' => array() 
    ), 
    (object)array(
     'id'   => 4, 
     'titre'  => "Jambon", 
     'attributs' => array() 
    ), 
    (object)array(
     'id'   => 12, 
     'titre'  => "La Cabro d'or", 
     'attributs' => array(
      (object)array("id" => 1), 
      (object)array("id" => 8) 
     ) 
    ) 
); 


$tab_json = array (
    (object)array(
     'id' => 1, 
     'titre' => 'Anchois', 
     'attributs' => 
     array (
     ), 
    ), 
    (object)array(
     'id' => 4, 
     'titre' => 'Jambon', 
     'attributs' => 
     array (
     ), 
    ), 
    (object)array(
     'id' => 12, 
     'titre' => 'La Cabro d\'or', 
     'attributs' => 
     array (
     ), 
    ), 
    (object)array(
     'id' => 25, 
     'titre' => 'Vin rouge ou rosé', 
     'attributs' => 
     array (
     ), 
    ), 
    (object)array(
     'id' => 22, 
     'titre' => 'Crème oignons lardons', 
     'attributs' => 
     array (
      (object)array(
       'id' => 1, 
      ), 
      (object)array(
       'id' => 2, 
      ), 
     ), 
    ) 
); 
echo "tab = "; var_export($tab); echo "\n"; 
echo "tab_json = "; var_export($tab_json); echo "\n"; 
echo "tab_json = "; var_export(array_diff($tab_json,$tab)); echo "\n"; 
?> 
+0

Вы сравниваете идентичные объекты или разные объекты с одинаковыми данными? –

+0

Объекты с теми же свойствами, но ** возможно меньше ** объектов, или ** возможно ** значения свойств изменились (это то, что я хочу угадать на самом деле) –

+0

Я только что добавил конкретный образец, который я хотел бы работать. –

ответ

0

Я сделал функцию, которая, кажется, сравнивает «ok»: я «конкатенирую» свойства обоих массивов, чтобы сделать «строки», а затем использовать функцию strcmp() для возврата результата. Итак, когда значения различны, они меняются на строку, а когда речь заходит о «под» массивах, они преобразуются в строку = «Array», поэтому сравнение == 0 так, что «вспомогательные» массивы игнорируются (именно этого я и хотел).

Это работает. Если вы найдете пример, который может показать мне, что он не работает, поделитесь им со мной в комментарии. Благодаря!

$difference = array_udiff($tab_json, $tab, function($a, $b) { 
    $d=array_diff_assoc(get_object_vars($a), get_object_vars($b)); 
    if (count($d)>0) { 
     $s0=''; 
     $s1=''; 
     foreach ($d as $k=>$val) { 
      $r0=(string)$val; 
      $r1=(string)$b->$k; 
      $l0 = mb_strlen($r0); 
      $l1 = mb_strlen($r1); 
      for (;$l0<$l1;$l0++) { 
       $r0=' '.$r0; 
      } 
      for (;$l1<$l0;$l1++) { 
       $r1=' '.$r1; 
      } 
      $s0.=$r0; 
      $s1.=$r1; 
     } 
     return strcmp($s0,$s1); 
    } 
    return 0; 
}); 
echo "difference = "; var_export($difference); echo "\n"; 
0

Вы можете использовать array_udiff:

$difference = array_udiff($tab, $tab_json, function($a, $b) { 
    return $a == $b; 
}); 

Простой array_diff не может использоваться, поскольку он сравнивает только строковые значения одинаково. Для запуска этого примера требуется PHP 5.3, но вы можете настроить его на PHP 5.2, перемещая замыкание на внешнюю функцию и передавая его имя в качестве третьего параметра на array_udiff.

Обратите внимание, что заказ на array_udiff имеет значение. Если вы пройдете $tab_json, сначала вы можете получить разные результаты.

+0

Спасибо за ваш ответ, но, к сожалению, он не работа с образцом, который я только что добавил в моем вопросе: он возвращает пустой массив. –

+0

Если я попробую этот код для закрытия: 'return (count (array_diff (get_object_vars ($ a), get_object_vars ($ b))))> 0;' он не работает, но результат не пустой массив (Теперь я могу быть ближе к ценному решению). Еще ищете. –

+0

У вас есть образец для объектов, которые вы сравниваете? – alganet

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