これは非常に明白な質問であり、まさにこれを行う関数があると確信していますが、見つけることができないようです。 PHPでは、可能な限り効率的に配列に重複があるかどうかを知りたいです。 array_unique
のようにそれらを削除したくはありません。また、array_unique
を実行して元の配列と比較し、それらが同じかどうかを確認したくはありません。非効率的な。パフォーマンスに関する限り、「予想される条件」は、配列に重複がないことです。
次のようなことができるようになりたい
if (no_dupes($array))
// this deals with arrays without duplicates
else
// this deals with arrays with duplicates
私が考えていない明らかな機能はありますか?
PHP配列?
は正しいタイトルで、非常によく似た質問ですが、実際に質問を読んだ場合、彼はarray_count_valuesを探しています。
できるよ:
function has_dupes($array) {
$dupe_array = array();
foreach ($array as $val) {
if (++$dupe_array[$val] > 1) {
return true;
}
}
return false;
}
array_unique()
の後ではないことを知っています。しかし、あなたは見つけることができません 魔法の obvious関数も、ネイティブ関数を使用するよりも高速な記述もできません。
私が提案する:
_function array_has_dupes($array) {
// streamline per @Felix
return count($array) !== count(array_unique($array));
}
_
array_unique()
の2番目のパラメーターを調整して、比較のニーズに合わせます。
パフォーマンスとマイクロ最適化に関心がある場合は、このワンライナーを確認してください。
function no_dupes(array $input_array) {
return count($input_array) === count(array_flip($input_array));
}
説明:
関数は、$input_array
の配列要素の数を array_flip 'ed要素と比較します。値はキーになり、推測します。キーは連想配列内で一意でなければならないため、一意の値が失われたり、要素の最終数が元の値よりも少なくなったりしません。
手動 で述べたように、配列キーはint
またはstring
のタイプのみであるため、これは比較する元の配列値に含めることができます。それ以外の場合はPHPは、予期しない結果で casting を開始します。
テストケース:
<?php
$elements = array_merge(range(1,10000000),[1]);
$time = microtime(true);
accepted_solution($elements);
echo 'Accepted solution: ', (microtime(true) - $time), 's', PHP_EOL;
$time = microtime(true);
most_voted_solution($elements);
echo 'Most voted solution: ', (microtime(true) - $time), 's', PHP_EOL;
$time = microtime(true);
this_answer_solution($elements);
echo 'This answer solution: ', (microtime(true) - $time), 's', PHP_EOL;
function accepted_solution($array){
$dupe_array = array();
foreach($array as $val){
// sorry, but I had to add below line to remove millions of notices
if(!isset($dupe_array[$val])){$dupe_array[$val]=0;}
if(++$dupe_array[$val] > 1){
return true;
}
}
return false;
}
function most_voted_solution($array) {
return count($array) !== count(array_unique($array));
}
function this_answer_solution(array $input_array) {
return count($input_array) === count(array_flip($input_array));
}
特定の条件では、一意の値が巨大な配列の先頭近くにない場合、受け入れられたソリューションがより高速になる可能性があることに注意してください。
$duplicate = false;
if(count(array) != count(array_unique(array))){
$duplicate = true;
}
これについての私の見解は…ベンチマークを行った結果、これがこのための最速の方法であることがわかりました。
function has_duplicates( $array ) {
return count( array_keys( array_flip( $array ) ) ) !== count( $array );
}
…または状況によっては、これはわずかに高速になる可能性があります。
function has_duplicates( $array ) {
$array = array_count_values( $array );
rsort( $array );
return $array[0] > 1;
}
count($array) > count(array_unique($array));
重複する場合はfalse
、重複しない場合はtrue
になります。
シンプルで愚かなことをしてください! ;)
シンプルOR logic ...
function checkDuplicatesInArray($array){
$duplicates=FALSE;
foreach($array as $k=>$i){
if(!isset($value_{$i})){
$value_{$i}=TRUE;
}
else{
$duplicates|=TRUE;
}
}
return ($duplicates);
}
よろしく!
この便利なソリューションを見つける
function get_duplicates( $array ) {
return array_unique( array_diff_assoc( $array, array_unique( $array ) ) );
}
カウントが0より大きい場合は、他の一意の重複よりも多くなります。
私はこれを使用しています:
if(count($array)==count(array_count_values($array))){
echo("all values are unique");
}else{
echo("there's dupe values");
}
最速かどうかはわかりませんが、これまでのところうまくいきます
PHPには、配列内の出現回数をカウントする機能があります http://www.php.net/manual/en/function.array-count-values.php
そのようにすることもできます:一意のelseがfalseを返す場合、これはtrueを返します。
$nofollow = (count($modelIdArr) !== count(array_unique($modelIdArr))) ? true : false;
私が考えることができる2つの効率的な方法:
すべての値をある種のハッシュテーブルに挿入し、挿入する値が既にその中にあるかどうかを確認します(O(n)時間とO(n)スペースが予想されます)
配列を並べ替え、隣接セルが等しいかどうかを確認します(O(nlogn) timeおよびO(1)またはO(n)スペースは並べ替えに応じてアルゴリズム)
stormdrainの解決策はおそらくO(n ^ 2)であり、各要素の配列をスキャンして重複を検索することを伴う解決策と同様です。
あなたが具体的に言ったように、あなたはarray_unique
他の回答はおそらくより良いという事実にもかかわらず無視します。
array_count_values() を使用して、結果の配列に1より大きい値があるかどうかを確認してみませんか?