Может ли функция in_array
сравнивать объекты?
Например, у меня есть массив объектов, и я хочу добавить их к другому массиву. Можно ли проверить, был ли объект уже добавлен так:
in_array($distinct, $object);
или есть другой способ?
Функция in_array не может сравнивать объекты.
Вы должны создавать уникальные пары ключ-значение из ваших объектов и только сравнивать эти ключи при вставке нового объекта в ваш окончательный массив.
Предполагая, что каждый объект имеет уникальное свойство id
, возможным решением было бы:
$unique_objects = array(); // $data represents your object collection foreach ($data as $item) { if (!array_key_exists($item->id, $unique_objects)) { $unique_objects[$item->id] = $obj; } }
Вы можете использовать строгое сравнение:
in_array($object, $array, TRUE);
Пример использования:
$a = new stdClass(); $a->x = 42; $b = new stdClass(); $b->y = 42; $c = new stdClass(); $c->x = 42; $array = array($a,$b); echo in_array($a, $array, true); // 1 echo in_array($b, $array, true); // 1 echo in_array($c, $array, true); //
См. http://php.net/manual/en/function.spl-object-hash.php
if ( ! array_key_exists( spl_object_hash( $obj ), $objects ) ) { $objects[ spl_object_hash( $obj ) ] = $obj; }
ура
Я не знаю, связано ли это с новой версией PHP, но в моем проекте, используя PHP 5.3.16 на Ubuntu 12.04, это сработало. Он нашел объект иглы в моем массиве объектов. Я также дважды проверял загрузку другого объекта того же класса и проверку его на содержимое массива, которое не содержало этот объект, и оно действительно вернулось.
Так что да, in_array
может сравнивать объекты.
Если «STRICT» является «FALSE», сравнение производится путем преобразования в строку элементов. Поэтому, если вы переопределите магическую функцию __toString, вы должны быть доступны для сравнения элементов объектов.
Я придумал несколько другое, я думаю, более надежный вариант.
function array_add_unique(&$array, $new, $test, $cb) { if(is_array($array) && count($array)>0) { for($i = 0; $i < count($array); $i++) { if( $array[$i][$test] == $new[$test] ) { $do = $cb($array[$i], $new); if(is_bool($do) && $do) { $array[$i] = $new; } else if(!is_bool($do)) { $array[$i] = $do; } return; } } } array_push($array, $new); }
Преимущество этого решения состоит в том, что он включает определяемый пользователем обратный вызов для обработки конфликтов. Когда вы добавляете уникальные объекты, вы можете сохранить свойства как из старого, так и из нового объекта.
Обратный вызов, который может быть анонимной функцией, получает как новый объект, так и существующий объект, поэтому пользователь может иметь собственный расчет. Верните true, чтобы просто заменить существующий объект или вернуть новый объект (non-bool) для его замены.
Однако я не знаю, как это работает на больших наборах данных.
Существует множество способов сделать это, как вы можете видеть. Я просто подумал, что добавлю еще один. Я не знаю почему, но при работе с объектными массивами мне нравится использовать функции массива, которые используют обратные вызовы.
Если у ваших объектов есть какой-либо идентификатор, который они должны, если вы хотите проверить их на дублирование, будет работать следующее:
$found = array_filter($uniqueObjects, function($uniqueObject) use ($object) { return $uniqueObject->id == $object->id }); if (!$found) { $uniqueObjects[] = $object; }
$object
– объект, который вы ищете, и $uniqueObjects
– это массив объектов, которые вы ищете, чтобы увидеть, существует ли он. Просто сопоставьте uniqueObject и объект с идентификационным свойством, таким как id
.