Как array_diff работает?

Как делает array_diff() работа? Это, очевидно, не могло работать следующим образом:

function array_diff($arraya, $arrayb)
{
    $diffs = array();
    foreach ($arraya as $keya => $valuea)
    {
        $equaltag = 0;
        foreach ($arrayb as $valueb)     
        {
            if ($valuea == $valueb)
            {
                $equaltag =1;
                break;
            }
        }
        if ($equaltag == o)
        {
              $diffs[$keya]=$valuea;
        }

    }
    return $diffs;                          
}                                  //couldn't be worse than this

Кто-либо знает лучшее решение?

РЕДАКТИРОВАНИЕ @animuson:

function array_diff($arraya, $arrayb)
{
    foreach ($arraya as $keya => $valuea)
    {
        if (in_array($valuea, $arrayb))
        {
            unset($arraya[$keya]);
        }
    }
    return $arraya;
}
23
задан Undo 28 October 2013 в 01:02
поделиться

3 ответа

ОБНОВЛЕНИЕ

  • см. Ниже для более быстрого / лучшего кода.

  • Поведение array_diff намного лучше в php 5.3.4, но все же в ~ 10 раз медленнее, чем функция Лео.

  • также стоит отметить, что эти функции не строго эквивалентны array_diff , поскольку они не поддерживают ключи массива, то есть my_array_diff (x, y) == array_values ​​(array_diff (x, y )) .

/ ОБНОВЛЕНИЕ

Лучшее решение - использовать хэш-карты

function my_array_diff($a, $b) {
    $map = $out = array();
    foreach($a as $val) $map[$val] = 1;
    foreach($b as $val) if(isset($map[$val])) $map[$val] = 0;
    foreach($map as $val => $ok) if($ok) $out[] = $val;
    return $out;
}

$a = array('A', 'B', 'C', 'D');
$b = array('X', 'C', 'A', 'Y');

print_r(my_array_diff($a, $b)); // B, D

тест

function your_array_diff($arraya, $arrayb)
{
    foreach ($arraya as $keya => $valuea)
    {
        if (in_array($valuea, $arrayb))
        {
            unset($arraya[$keya]);
        }
    }
    return $arraya;
}

$a = range(1, 10000);
$b = range(5000, 15000);

shuffle($a);
shuffle($b);

$ts = microtime(true);
my_array_diff($a, $b);
printf("ME =%.4f\n", microtime(true) - $ts);

$ts = microtime(true);
your_array_diff($a, $b);
printf("YOU=%.4f\n", microtime(true) - $ts);

результат

ME =0.0137
YOU=3.6282

Есть вопросы? ;)

и, просто для удовольствия,

$ts = microtime(true);
array_diff($a, $b);
printf("PHP=%.4f\n", microtime(true) - $ts);

результат

ME =0.0140
YOU=3.6706
PHP=19.5980

, это невероятно!

23
ответ дан 29 November 2019 в 01:08
поделиться

Из PHP: «Возвращает массив, содержащий все записи из array1, которых нет ни в одном из других массивов».

Итак, вы просто проверьте array1 для всех arrayN , и любые значения в array1 , которые не присутствуют ни в одном из этих массивов, будут возвращены в новом массиве.

Вам даже не обязательно перебирать все значения array1 . Для всех дополнительных массивов прокрутите их значения и проверьте, является ли каждое значение in_array ($ array1, $ value) .

-2
ответ дан 29 November 2019 в 01:08
поделиться

Лучшее решение, чтобы узнать, как это работает, взглянуть на его исходный код; -)
(Ну, это одна из возможностей открытого исходного кода - и если вы видите возможную оптимизацию, вы можете отправить патч ;-))

Для array_diff он должен быть в ext / standard - что означает для PHP 5.3 он должен быть там: branch / PHP_5_3 / ext / standard

И тогда файл array.c выглядит вполне вероятной целью; функция php_array_diff , строка 3381, похоже, соответствует array_diff .


(Удачи в прохождении кода: он довольно длинный ...)

7
ответ дан 29 November 2019 в 01:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: