Найти дубликаты в массиве объектов на основе определенных ключей

моя цель – найти дубликаты в массиве объектов, но только для конкретных объектных переменных.

Вместо того, чтобы использовать две петли foreach, такие как следующие, я ищу лучший (более элегантный) способ найти дубликаты:

foreach ($data as $date) { foreach ($data as $innerDate) { if ($date->birthday == $innerDate->birthday && $date->street == $innerDate->street && $date->streetnr == $innerDate->streetnr && $date->zipcode == $innerDate->zipcode && $date->twinid == $innerDate->twinid && $date !== $innerDate) { // Duple } } } 

Благодаря!


Теперь я использую следующий код, основанный на идее Тарило:

 usort($data, function($obj_a, $obj_b){ if ($obj_a->birthday == $obj_b->birthday && $obj_a->street == $obj_b->street && $obj_a->streetnr == $obj_b->streetnr && $obj_a->zipcode == $obj_b->zipcode && $obj_a->twinid == $obj_b->twinid) { // Duple } }); 

Выглядит намного лучше, чем два foreach-Loops 😉

Сначала вы можете отсортировать массив, а затем перебрать отсортированный массив. Таким образом, вам нужно сравнить текущий объект со следующим / предыдущим объектом. Ваш текущий алгоритм O (n ^ 2) эффективен, но после сортировки он будет (сортировка + цикл) = (O (log n) + O (n)) эффективна. Где n – количество объектов в вашем массиве.

Вы пытались использовать функцию in_array() в php?

Для получения дополнительной информации о in_array () используйте этот URL-адрес

http://php.net/manual/fr/function.in-array.php

Поскольку $ data является массивом, мы можем использовать функцию array_ *

Попробуйте это, работает на моем конце (PHP 5.2.0).

 if ($data != array_unique($data)) { echo 'oops, this variable has one or more duplicate item(s)'; die; } 

Это дает вам массив с похожими элементами, сгруппированными. Должен быть быстрее для больших наборов данных: O (2n) с дополнительной стоимостью для строки concat и рассчитывать на результирующие группы. Из-за хэш-карты требуется немного больше памяти.

 $hashmap = array(); foreach ($data as $date) { $hash = $date->zipcode.'-'.$date->street.'-'.$date->streetnr.'-'.$date->birthday.'-'.$date->twinid; if (!array_key_exists($hash, $hashmap)) { $hashmap[$hash] = array(); } $hashmap[$hash][] = $date; } foreach ($hashmap as $entry) { if (count($entry) > 1) { foreach ($entry as $date) { // $date is a duplicate } } }