array_unique vs array_flip

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

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 ) 

Solutions Collecting From Web of "array_unique vs array_flip"

Я оценил это для вас: 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) где ключи остаются неизменными.

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

 ➜ 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 

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

Внимание: этот метод НЕ является заменой для array_unique (). Он работает только для массивов со значениями, которые являются действительными ключами. (например: string, integer, вещи могут быть перенесены в 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', ) 

против:

 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', ) 

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

 array_keys( array_flip( $array ) ); 

что потребует больше времени

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