Как работает array_udiff ()?

Вот код, это очень просто:

<?php $tab = array ( (object)array( 'id' => 1,), (object)array( 'id' => 4,), (object)array( 'id' => 12,), (object)array( 'id' => 22,), (object)array( 'id' => 25,), ); $tab_json = array ( (object)array( 'id' => 1,), (object)array( 'id' => 4,), (object)array( 'id' => 12,), (object)array( 'id' => 22,), (object)array( 'id' => 25,), (object)array( 'id' => 2,), ); $difference = array_udiff($tab_json, $tab, function($a, $b) { echo $a->id." <-> ".$b->id."\n"; return (count(array_diff_assoc(get_object_vars($a), get_object_vars($b))))>0; }); ?> 

Вот результат:

 12 <-> 4 12 <-> 1 12 <-> 22 12 <-> 25 2 <-> 12 4 <-> 25 4 <-> 1 22 <-> 4 25 <-> 1 12 <-> 4 12 <-> 1 12 <-> 22 25 <-> 12 4 <-> 22 1 <-> 4 1 <-> 22 1 <-> 4 1 <-> 1 1 <-> 25 25 <-> 4 25 <-> 1 25 <-> 12 25 <-> 25 25 <-> 4 4 <-> 1 4 <-> 12 4 <-> 25 4 <-> 22 22 <-> 1 22 <-> 12 22 <-> 25 22 <-> 12 12 <-> 1 12 <-> 12 12 <-> 2 2 <-> 12 2 <-> 25 

Я не понимаю, как это вычисляется: посмотрите на 12 : он сравнивается более чем в 10 раз (тогда как я понимаю, его следует сравнивать не более, чем количество элементов второго массива), и более того, он сравнивается три раза с 1 !

Протестировано:

 PHP 5.3.9 PHP 5.3.2-1ubuntu4.14 

Способ, которым array_udiff() фактически дает свой результат, является, конечно, деталью реализации и может быть изменен. Поэтому, хотя то, что я говорю, может быть правдой прямо сейчас, вы не должны полагаться на это.

Например, если вам нужно использовать старую версию PHP, вы вполне можете реализовать версию совместимости функции, которая просто сравнивает каждый элемент первого массива с каждым элементом второго массива, отбрасывая любое совпадение.

С другой стороны, если вам нужна максимальная производительность, вы бы быстро сортировали элементы второго массива, а затем выполняли двоичный поиск элементов первого массива.

PHP 5.3, кажется, объединяет quicksort с линейным поиском. Тем не менее, он отменяет поиск, когда обнаруживается более крупный элемент.