array_unique vs array_flip - PullRequest
       44

array_unique vs array_flip

28 голосов
/ 30 ноября 2011

Если бы у меня был массив целых чисел со знаком, например:

Array
(
    [0] => -3
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 3
)

Чтобы получить уникальные значения, я бы инстинктивно использовал array_unique, но после рассмотрения я мог бы выполнить array_flip дважды, что имело бы тот же эффект,и я думаю, что это будет быстрее?

array_unique O (n log n) из-за операции сортировки, которую он использует

array_flip O (n)

Я прав в своих предположениях?

ОБНОВЛЕНИЕ / ПРИМЕР:

$intArray1 = array(-4,1,2,3);
print_r($intArray1);
$intArray1 = array_flip($intArray1);
print_r($intArray1);
$intArray1 = array_flip($intArray1);
print_r($intArray1);

Array
(
    [0] => -3
    [1] => 1
    [2] => 2
    [3] => 3
    [4] => 3
)
Array
(
    [-3] => 0
    [1] => 1
    [2] => 2
    [3] => 4
)
Array
(
    [0] => -3
    [1] => 1
    [2] => 2
    [4] => 3
)

Ответы [ 4 ]

29 голосов
/ 30 ноября 2011

Я тестировал его для вас: CodePad

Ваша интуиция была верна!

$test=array();
for($run=0; $run<1000; $run++)
$test[]=rand(0,100);

$time=microtime(true);

for($run=0; $run<100; $run++)
$out=array_unique($test);

$time=microtime(true)-$time;
echo 'Array Unique: '.$time."\n";

$time=microtime(true);

for($run=0; $run<100; $run++)
$out=array_keys(array_flip($test));

$time=microtime(true)-$time;
echo 'Keys Flip: '.$time."\n";

$time=microtime(true);

for($run=0; $run<100; $run++)
$out=array_flip(array_flip($test));

$time=microtime(true)-$time;
echo 'Flip Flip: '.$time."\n";

Выход:

Array Unique: 1.1829199790955
Keys Flip: 0.0084578990936279
Flip Flip: 0.0083951950073242

Обратите внимание, что array_keys(array_flip($array)) даст новые значения ключей по порядку, что во многих случаях может быть тем, что вы хотите (идентично, за исключением гораздо быстрее array_values(array_unique($array))), тогда как array_flip(array_flip($array)) идентично (за исключением гораздо быстрее) array_unique($array) где ключи остаются прежними.

3 голосов
/ 21 сентября 2015

Внимание: этот метод НЕ является заменой для array_unique ().Это работает только для массивов со значениями, которые являются действительными ключами.(например: строка, целое число, все может быть приведено к типу int).И, конечно, не работает для массивов объектов.

$input = [true, false, 1, 0, 1.2, "1", "two", "0"];
var_export(array_unique($input));
array (
  0 => true,
  1 => false,
  3 => 0,
  4 => 1.2,
  6 => 'two',
)

vs:

var_export(array_keys(array_flip($input)));

PHP Warning:  array_flip(): Can only flip STRING and INTEGER values! 
in php shell code on line 1

array (
  0 => 1,
  1 => 0,
  2 => 'two',
)
3 голосов
/ 30 ноября 2011

Нет ничего лучше, чем запустить собственный тест.

➜  8321620  cat first.php
<?php

$arr = array(-3, 1, 2, 3, 3);

for($i = 0; $i <= 1000000; $i++) {
    array_unique($arr);
}
➜  8321620  time php first.php
php first.php  3.24s user 0.01s system 99% cpu 3.251 total
➜  8321620  cat second.php
<?php

$arr = array(-3, 1, 2, 3, 3);

for($i = 0; $i <= 1000000; $i++) {
    array_flip(array_flip($arr));
}
➜  8321620  time php second.php
php second.php  1.50s user 0.01s system 99% cpu 1.514 total

Обновление: массив с 1000 элементами.

➜  8321620  cat first.php
<?php

$arr = array();
for($i = 0; $i <= 1000; $i++) {
    $arr[] = rand(0, 1000);
}

for($i = 0; $i <= 10000; $i++) {
    array_unique($arr);
}
➜  8321620  time php first.php
php first.php  27.50s user 0.03s system 99% cpu 27.534 total
➜  8321620  cat second.php
<?php

$arr = array();
for($i = 0; $i <= 1000; $i++) {
    $arr[] = rand(0, 1000);
}

for($i = 0; $i <= 10000; $i++) {
    array_flip(array_flip($arr));
}
➜  8321620  time php second.php 
php second.php  1.59s user 0.01s system 99% cpu 1.604 total

Так что да, ваше предположение было верным.

0 голосов
/ 30 ноября 2011

вам придется использовать

array_keys( array_flip( $array ) );

, что займет больше времени

Я бы выбрал array_unique.Это имеет дополнительное преимущество объяснения того, что происходит.

...