Сравнение двух массивов на наличие одинаковых значений (дублированных или нет, с учетом жонглирования типами) можно выполнить с помощью array_diff()
. в обе стороны:
!array_diff($a, $b) && !array_diff($b, $a);
Это дает TRUE
, если оба массива имеют одинаковые значения (после жонглирования типами). FALSE
иначе. Примеры:
function array_equal_values(array $a, array $b) {
return !array_diff($a, $b) && !array_diff($b, $a);
}
array_equal_values([1], []); # FALSE
array_equal_values([], [1]); # FALSE
array_equal_values(['1'], [1]); # TRUE
array_equal_values(['1'], [1, 1, '1']); # TRUE
Как показывает этот пример, array_diff
исключает ключи массива из уравнения и не заботится ни о порядке значений, ни о том, дублируются значения или нет.
Если дублирование должно иметь значение, это становится более сложным. Что касается «простых» значений (работают только строковые и целочисленные значения), array_count_values()
вступает в игру для сбора информации. о том, какое значение, как часто внутри массива. Эту информацию можно легко сравнить с ==
:
array_count_values($a) == array_count_values($b);
Это дает TRUE
, если оба массива имеют одинаковые значения (после жонглирования типами) за одинаковое количество времени. FALSE
иначе. Примеры:
function array_equal_values(array $a, array $b) {
return array_count_values($a) == array_count_values($b);
}
array_equal_values([2, 1], [1, 2]); # TRUE
array_equal_values([2, 1, 2], [1, 2, 2]); # TRUE
array_equal_values(['2', '2'], [2, '2.0']); # FALSE
array_equal_values(['2.0', '2'], [2, '2.0']); # TRUE
Это можно дополнительно оптимизировать, сначала сравнив количество двух массивов, что относительно дешево, и быстрый тест, чтобы отличить большинство массивов, когда дублирование значений подсчета имеет значение.
Пока что эти примеры частично ограничены строковыми и целочисленными значениями, и строгое сравнение с array_diff
также невозможно. Для строгого сравнения больше подходит array_search
. Поэтому значения необходимо подсчитывать и индексировать, чтобы их можно было сравнить, поскольку просто превратить их в ключ (как это делает array_search
) не получится.
Это немного больше работы. Однако в конце сравнение такое же, как и раньше:
$count($a) == $count($b);
Разница только в $count
:
$table = [];
$count = function (array $array) use (&$table) {
$exit = (bool)$table;
$result = [];
foreach ($array as $value) {
$key = array_search($value, $table, true);
if (FALSE !== $key) {
if (!isset($result[$key])) {
$result[$key] = 1;
} else {
$result[$key]++;
}
continue;
}
if ($exit) {
break;
}
$key = count($table);
$table[$key] = $value;
$result[$key] = 1;
}
return $result;
};
Это сохраняет таблицу значений, чтобы оба массива могли использовать один и тот же индекс. Также можно выйти досрочно в первый раз, когда во втором массиве появляется новое значение.
Эта функция также может добавить контекст strict с помощью дополнительного параметра. А добавление еще одного дополнительного параметра позволило бы включить поиск дубликатов или нет. Полный пример:
function array_equal_values(array $a, array $b, $strict = FALSE, $allow_duplicate_values = TRUE) {
$add = (int)!$allow_duplicate_values;
if ($add and count($a) !== count($b)) {
return FALSE;
}
$table = [];
$count = function (array $array) use (&$table, $add, $strict) {
$exit = (bool)$table;
$result = [];
foreach ($array as $value) {
$key = array_search($value, $table, $strict);
if (FALSE !== $key) {
if (!isset($result[$key])) {
$result[$key] = 1;
} else {
$result[$key] += $add;
}
continue;
}
if ($exit) {
break;
}
$key = count($table);
$table[$key] = $value;
$result[$key] = 1;
}
return $result;
};
return $count($a) == $count($b);
}
Примеры использования:
array_equal_values(['2.0', '2', 2], ['2', '2.0', 2], TRUE); # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE); # TRUE
array_equal_values(['2.0', '2', 2, 2], ['2', '2.0', 2], TRUE, FALSE); # FALSE
array_equal_values(['2'], ['2'], TRUE, FALSE); # TRUE
array_equal_values([2], ['2', 2]); # TRUE
array_equal_values([2], ['2', 2], FALSE); # TRUE
array_equal_values([2], ['2', 2], FALSE, TRUE); # FALSE
person
hakre
schedule
14.07.2013