При поиске решения для идентификации дубликатов в массиве я наткнулся на многие виды решений в расчете на array_count_values
или array_unique
.Но все эти решения не заботятся об объектах в массиве.
array_count_values
выдает E_WARNING
для каждого значения, которое не является string
или integer
.
array_unique
заботится об элементах различного типа, если установлена опция SORT_REGULAR
.Но рассмотрим вариант использования следующим образом.
class Foo
{
private $value;
public function __construct( $value )
{
$this->value = $value;
}
}
$f1 = new Foo( 42 );
$f2 = $f1;
$f3 = new Foo( 42 );
$f4 = new Foo( '42' );
$f5 = new Foo( 'Bar' );
$a = [ $f1, $f2, $f3, $f4, $f5 ];
После объединения с array_unqiue
я ожидал получить массив из 4 элементов [ $f1, $f3, $f4, $f5 ]
.Но в нем говорится, что array_unqiue
работает свободно, и я получил [ $f1, $f5 ]
, а это не тот результат, который мне нужен.
В моем случае я написал коллекцию, работающую как набор.Я могу передать некоторые начальные элементы.Эти элементы должны быть проверены.Если один элемент является дубликатом, должно быть выброшено исключение.Для беспорядочно набранного array_unqiue
я придумал это решение (которое можно очень легко адаптировать для объединения массива).
$boundN = count( $elements );
$boundM = $boundN - 1;
for ( $m = 0; $m < $boundM; $m++ )
{
for ( $n = $m + 1; $n < $boundN; $n++ )
{
if ( $elements[ $m ] === $elements[ $n ] )
{
throw new DuplicateElementException( 'The initial values contain duplicates.' );
}
}
}
По крайней мере, я минимизировал итерации во внутреннем цикле.Можно предположить, что все переданные элементы во внешнем цикле проверены и не должны проверяться снова.
Мой вопрос: есть ли более короткий алгоритм, равный алгоритмам, таким как Quick Search
или что-то еще?