PHP: количество раз, которое нужное значение встречается в массиве
Вроде бы мелочь, а неприятно - функции, позволяющей определить, сколько раз встречается в массиве нужное значение, в стандартных не обнаружил. Зато есть array_count_values
, которая подсчитает встречаемость всех значений, и есть array_filter
, способная сделать с массива нужный "срез".
Соответственно, если не заботиться о ресурсах и писать в типично-современном стиле, задачу можно сделать как минимум двумя способами :) Третий способ - написать классический код с поэлементным сканированием массива и проверкой элементов на равенство нужному значению.
Несложный тест на массиве из миллиона элементов показывает, что array_count_values
лучше всего, классический код в 2-2,5 раза хуже, а вот array_filter
в данном случае - очень медленно. Подумайте, почему. Обратите внимание, что array_count_value1
без указания global $val;
работать с безымянной callback-функцией не будет (встроенная функция фильтрации элементов не возьмёт $val
из параметров array_count_value1
). Такие уж у PHP области видимости.
Вот полный исходник и результаты теста.
<?php function array_count_value1 ($array,$val) { return count(array_filter($array, function($item) { global $val; return $item==$val; })); } function array_count_value2 ($array,$val) { $a = array_count_values ($array); foreach ($a as $key=>$value) if ($key==$val) return $value; return 0; } function array_count_value3 ($array,$val) { $count=0; foreach ($array as $item) if ($item==$val) $count++; return $count; } $a = array (); for ($i=0; $i<1e6; $i++) $a[] = rand(0,99); $val = 1; $start = microtime(true); $r1 = array_count_value1 ($a,$val); $end = microtime(true); echo '<br>function 1, result='.$r1.', '.round($end-$start,4).' ms'; $start = microtime(true); $r2=array_count_value2 ($a,$val); $end = microtime(true); echo '<br>function 2, result='.$r2.', '.round($end-$start,4).' ms'; $start = microtime(true); $r3=array_count_value3 ($a,$val); $end = microtime(true); echo '<br>function 3, result='.$r3.', '.round($end-$start,4).' ms'; ?>
function 1, result=10007, 2.2433 ms function 2, result=10007, 0.0231 ms function 3, result=10007, 0.05775 ms
В PHP7 и на мощном компьютере результаты более обнадёживающие, но тенденция та же:
function 1, result=9972, 0.0481 ms function 2, result=9972, 0.0035 ms function 3, result=9972, 0.0111 ms
16.10.2015, 16:16 [7333 просмотра]