配列のすべての値が等しいかどうかを確認します


190

すべての値が等しい配列を見つける必要があります。これを行う最も速い方法は何ですか?ループして値を比較するだけですか?

['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false

1
@TJCrowder私はあなたがすでに最善の解決策を考えているに違いない;)
VisioN

2
@TJCrowder:質問者が実際に回答を受け入れる意欲は言うまでもありません。担当者が1人のユーザーは、最近、コピーアンドペースト可能な回答があるとすぐに終了する質問と実行のタイプのようです。
Cerbrus 2013

1
このアプローチの周りの何かがうまくいくはずですか?a.join(',').split(a[0]).length === a.length + 1
Jashwant 2013

1
@TomášZato: "OP"は "オリジナルのポスター"(質問者)を意味します。
TJクラウダー2013

回答:


289
const allEqual = arr => arr.every( v => v === arr[0] )
allEqual( [1,1,1,1] )  // true

またはワンライナー:

[1,1,1,1].every( (val, i, arr) => val === arr[0] )   // true

Array.prototype.every(MDNから):every()メソッドは、配列内のすべての要素が、提供された関数によって実装されたテストに合格するかどうかをテストします。


11
簡潔さはウィットの魂です
svarog

1
jsperfケースを作成しまし。この方法は、ほとんどの候補よりも優れています。
Junliang Huang

1
const everythings_equal = array => array.every(thing => thing === array[0]);
КонстантинВан

8
使用するsome代わりにeveryarr.some( v => v !== arr[0] )。これは、と等しくないことが判明した最初の要素で早期に戻りarr[0]ます。

2
@Jan everyも早期に復帰します。
golopot

111

編集:赤い忍者になる:

!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });

結果:

var array = ["a", "a", "a"] => result: "true"
var array = ["a", "b", "a"] => result: "false"
var array = ["false", ""] => result: "false"
var array = ["false", false] => result: "false"
var array = ["false", "false"] => result: "true"
var array = [NaN, NaN] => result: "false" 

警告:

var array = [] => result: TypeError thrown

これは、initialValueを渡さないためです。したがって、array.length最初に確認することをお勧めします。


5
パーティーに少し遅れる可能性があります...配列がfalses で構成されている場合、これは機能しません。たとえば、[false、false、false] .reduce(function(a、b){return(a === b)?a:false;});を試してください。
George Flourentzos 2014年

3
@Martin:["false", ""]リターンtrue:/
dalgard

6
これは、を使用してワンランク上のものにすることができますNaNNaN === NaNNaN !== NaNは両方ともfalseであるため、prevがNaNに設定されると、値を取得できないことが保証されます。また、二重否定を追加するtruefalse、結果はandに変換されますNaN。最終フォーム:!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
フィリペシルバ

3
反対。要素が等しいが偽物である場合はどうなりますか?
КонстантинВан

3
これはブール値では機能しないため、反対票を投じました。
Tyguy7 2018

62

これは機能します。Arrayにメソッドを作成するには、プロトタイプを使用します。

if (Array.prototype.allValuesSame === undefined) {
  Array.prototype.allValuesSame = function() {
    for (let i = 1; i < this.length; i++) {
      if (this[i] !== this[0]) {
        return false;
      }
    }
    return true;
  }
}

これを次のように呼び出します。

let a = ['a', 'a', 'a'];
let b = a.allValuesSame(); // true
a = ['a', 'b', 'a'];
b = a.allValuesSame();     // false

5
非常にいいですが、注意してください:IEはこの方法でプロトタイプを割り当てることをサポートしていません。とにかく使います。
トマーシュZato -復活モニカ

5
@TomášZato:IEは、Array.prototype(IE6でも)十分な拡張をサポートしています。一部の古いバージョンのIEが拡張をサポートしていないのは、DOM要素のプロトタイプのみです。
TJクラウダー2013

4
ビルトインのプロトタイプにサルのパッチを適用するのは良い考えではないと思います。複数のライブラリがそれを行うと、デバッグが非常に困難な予期しない動作が発生する可能性があります。
Mark Wilbur

1
@MarkWilbur +1特に次の配列でfor..inループを実行するallValuesSameと、ループに入ります
Olivier Pons

1
私は先に進んで、意図を変えることなくこれを近代化しました。
ポリワール氏1

30

JavaScript 1.6では、以下を使用できますArray.every

function AllTheSame(array) {
    var first = array[0];
    return array.every(function(element) {
        return element === first;
    });
}

おそらく配列に要素がない場合など、おそらくいくつかの健全性チェックが必要です。(また、すべての要素がNaN以降の場合、これは機能NaN !== NaNしませんが、それは問題ではありません...よろしいですか?)


30

配列をセットに変えることができます。セットのサイズが1の場合、配列のすべての要素は同じです。

function allEqual(arr) {
  return new Set(arr).size == 1;
}

allEqual(['a', 'a', 'a', 'a']); // true
allEqual(['a', 'a', 'b', 'a']); // false

鮮やかさ。この場合、それallEqual([NaN, NaN])が与えることtrueに注意してください。
КонстантинВан

12

また、パフォーマンスの比較のためにベンチマークも行いました。

function allAreEqual(array){
    if(!array.length) return true;
    // I also made sure it works with [false, false] array
    return array.reduce(function(a, b){return (a === b)?a:(!b);}) === array[0];
}
function same(a) {
    if (!a.length) return true;
    return !a.filter(function (e) {
        return e !== a[0];
    }).length;
}

function allTheSame(array) {
    var first = array[0];
    return array.every(function(element) {
        return element === first;
    });
}

function useSome(array){
    return !array.some(function(value, index, array){
        return value !== array[0];
    });
}

結果:

allAreEqual x 47,565 ops/sec ±0.16% (100 runs sampled)
same x 42,529 ops/sec ±1.74% (92 runs sampled)
allTheSame x 66,437 ops/sec ±0.45% (102 runs sampled)
useSome x 70,102 ops/sec ±0.27% (100 runs sampled)

したがって、組み込みのarray.some()を使用することが、サンプリングされたメソッドの中で最も速い方法です。


3
ここでよりパフォーマンスの高いものを確認することをお勧めします。Array#someときどきパフォーマンスが向上する理由は、コールバック関数がtrueを返すと、反復が停止するためです。したがって、すべての要素が実際に等しい場合、パフォーマンスはと同じになりArray#everyます。また、すべての要素が等しくない場合の相対的なパフォーマンスは、最初の一致しない要素のインデックスによって異なります。
ダンマクトフ、2015年

3
良いですね。lolを使用する関数でそれぞれに名前を付けることができます。例:削減、フィルタリング、すべて、一部
Z. Khullah、2017

ここで、ネイティブのforループは、これらすべての係数を5倍上回っているに
違いありません

9

アンダースコア/ロダッシュを使用した最短の回答

function elementsEqual(arr) {
    return !_.without(arr, arr[0]).length
}

スペック:

elementsEqual(null) // throws error
elementsEqual([]) // true
elementsEqual({}) // true
elementsEqual([1]) // true
elementsEqual([1,2]) // false
elementsEqual(NaN) // true

編集:

または、トムの答えに触発されてさらに短く:

function elementsEqual2(arr) {
    return _.uniq(arr).length <= 1;
}

スペック:

elementsEqual2(null) // true (beware, it's different than above)
elementsEqual2([]) // true
elementsEqual2({}) // true
elementsEqual2([1]) // true
elementsEqual2([1,2]) // false
elementsEqual2(NaN) // true

6

すでにunderscore.jsを使用している場合は、次のオプションを使用します_.uniq

function allEqual(arr) {
    return _.uniq(arr).length === 1;
}

_.uniq重複のない配列のバージョンを返します。すべての値が同じ場合、長さは1になります。

コメントで述べたように、空の配列がを返すことが予想trueされる場合、その場合もチェックする必要があります。

function allEqual(arr) {
    return arr.length === 0 || _.uniq(arr).length === 1;
}

しかし、配列が空の場合、答えはになりfalseます。と思うのtrueですが。に変更する.length <= 1だけで十分です。
平均ジョー

@Kasztanそれは公正なポイントです。そのケースをカバーするように回答を更新しました。
トムフェネック2017年

6

はい、次のようにフィルターを使用して確認することもできます。非常に単純で、すべての値を確認することは最初の値と同じです。

//ES6
function sameValues(arr) {
  return arr.filter((v,i,a)=>v===a[0]).length === arr.length;
} 

配列のすべてのメソッドを使用して行うこともできます:

//ES6
function sameValues(arr) {
  return arr.every((v,i,a)=>v===a[0]);
} 

そして、あなたは以下のようにあなたの配列をチェックすることができます:

sameValues(['a', 'a', 'a', 'a']); // true
sameValues(['a', 'a', 'b', 'a']); // false

または、それを頻繁に再利用する場合は、JavaScriptのネイティブの配列機能に追加できます。

//ES6
Array.prototype.sameValues = Array.prototype.sameValues || function(){
 this.every((v,i,a)=>v===a[0]);
}

そして、あなたは以下のようにあなたの配列をチェックすることができます:

['a', 'a', 'a', 'a'].sameValues(); // true
['a', 'a', 'b', 'a'].sameValues(); // false

5

Array.everyサポートされている場合に使用できます。

var equals = array.every(function(value, index, array){
    return value === array[0];
});

ループの代替アプローチは次のようなものです sort

var temp = array.slice(0).sort();
var equals = temp[0] === temp[temp.length - 1];

または、アイテムが質問のようである場合、次のような汚いものがあります

var equals = array.join('').split(array[0]).join('').length === 0;

また働きます。


あなたは最初の例を逆向きに持っています。する必要がありますequals = !array.some( (v,i,a) => v!==a[0] )。それ以外の場合は、値が最初の値と等しいことを確認しているだけです。もちろん、常にtrueになります:)
Mark Kahn

正確には、最初の段落で述べたのではsomeなく、代わりに使用しeveryました。:)キャッチをありがとう!
ZER0、2015


3

これを行う最も簡単な方法は、各値を次の値と比較するループを作成することだと思います。「チェーン」に中断がある限り、falseを返します。1つ目が2つ目と等しく、2つ目が3つ目と等しい、というように続く場合、配列のすべての要素が互いに等しいと結論付けることができます。

配列data []を指定すると、次を使用できます。

for(x=0;x<data.length - 1;x++){
    if (data[x] != data[x+1]){
        isEqual = false;            
    }
}
alert("All elements are equal is " + isEqual);


3

新しいソリューションを更新:インデックスを確認

 let a = ['a', 'a', 'b', 'a'];
 let a = ['a', 'a', 'a', 'a'];
 let check = (list) => list.every(item => list.indexOf(item) === 0);
 check(a); // false;
 check(b); // true;

ES6で更新:使用list.everyが最速の方法です。

 let a = ['a', 'a', 'b', 'a'];
 let check = (list) => list.every(item => item === list[0]);

古いバージョン:

      var listTrue = ['a', 'a', 'a', 'a'];
      var listFalse = ['a', 'a', 'a', 'ab'];

      function areWeTheSame(list) { 
         var sample = list[0];
         return (list.every((item) => item === sample));
      }

2

あなたはこれを使うことができます:

function same(a) {
    if (!a.length) return true;
    return !a.filter(function (e) {
        return e !== a[0];
    }).length;
}

関数は最初に配列が空かどうかをチェックします。そうである場合、その値は等しいです。それ以外の場合は、配列をフィルタリングし、最初の要素とは異なるすべての要素を取得します。そのような値がない場合=>配列には等しい要素のみが含まれ、それ以外の場合は含まれません。



1
var listTrue = ['a', 'a', 'a', 'a'];
var listFalse = ['a', 'a', 'a', 'ab'];

function areWeTheSame(list) { 
    var sample = list[0];
    return !(list.some(function(item) {
        return !(item == sample);
    }));
}

単にコードを貼り付けるのではなく、何をしたかについても説明してください。
Wouter J

1

それは簡単です。関数を作成し、パラメーターを渡します。その関数で、最初のインデックスを新しい変数にコピーします。次にforループを作成し、配列をループします。ループ内で、新しく作成された変数がループ内のすべての要素と等しいかどうかをチェックする条件を使用して、whileループを作成します。forループの完了後に等しい場合はtrueを返し、そうでない場合はwhileループ内でfalseを返します。

function isUniform(arra){
    var k=arra[0];
    for (var i = 0; i < arra.length; i++) {
        while(k!==arra[i]){
            return false;
        }
    }
    return true;
}

1

受け入れ答えは素晴らしい仕事が、私はほんの少しを追加したいです。===オブジェクトの配列の配列を比較していたため、使用できませんでしたが、アプリ全体で、私が強く推奨するfast-deep-equalパッケージを使用しています。これで、私のコードは次のようになります。

let areAllEqual = arrs.every((val, i, arr) => equal(val, arr[0]) );

そして私のデータは次のようになります:

[  
  [
    {
      "ID": 28,
      "AuthorID": 121,
      "VisitTypeID": 2
    },
    {
      "ID": 115,
      "AuthorID": 121,
      "VisitTypeID": 1
    },
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ],
  [
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ],
  [
    {
      "ID": 5,
      "AuthorID": 121,
      "VisitTypeID": 1
    },
    {
      "ID": 121,
      "AuthorID": 121,
      "VisitTypeID": 1
    }
  ]
]

1
  1. 配列を結合して文字列を作成します。
  2. 指定された配列の最初の文字を繰り返すことによって文字列を作成します
  3. 両方の文字列に一致

	function checkArray(array){
		return array.join("") == array[0].repeat(array.length);	
	}

	console.log('array: [a,a,a,a]: ' + checkArray(['a', 'a', 'a', 'a']));
	console.log('array: [a,a,b,a]: ' + checkArray(['a', 'a', 'b', 'a']));

これで完了です。


1

これで、セットを使用してそれを簡単に行うことができます。

let a= ['a', 'a', 'a', 'a']; // true
let b =['a', 'a', 'b', 'a'];// false

console.log(new Set(a).size === 1);
console.log(new Set(b).size === 1);


1

forループを使用できます。

function isEqual(arr) {
  var first = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (first !== arr[i]) {
      return false;
    }
  }
  return true;
}

0

まあ、これは本当にそれほど複雑ではありません。あなたも試さなかった強い疑いがあります。最初の値を選択して変数に保存し、forループ内で後続のすべての値を最初の値と比較します。
私は意図的にコードを共有しませんでした。がどのようforに使用され、どのように変数が比較されるかを見つけます。


8
この答えは好きではありません。2番目の値が3番目の値と同じであるかどうかなどは通知されません。ネストされたループは明らかにそれを行いますが、初心者のスクリプト作成者とは概念的に異なります。
jtromans 2013

3
@jtromans:等号の推移的な特性のため、A == BおよびA == Cの場合、B == Cがわかります。ネストされたループなどで「手動」で検証する必要はありません。単一の値(配列の最初の値であり、任意の値ではありません)に対する比較の繰り返しは、この回答が示唆するとおりであり、受け入れられた回答も同じです。
2013

@ov確かに、私の急いで質問を読み間違えました。このとき、すべての値が等しい(!
jtromans 2013

9
複雑ではありません。そして、ページ上の他の答えはどちらでもありません。しかし、私にとっては、この回答はほとんど役に立ちません。
チャーリー、

1
もともとは、OPが質問する前に考えようとしていると強く主張することを目的としていました。
トマーシュZato -復活モニカ

0

単純な1行のソリューション。最初のエントリで満たされた配列と比較するだけです。

if(arr.join('') === Array(arr.length).fill(arr[0]).join(''))

それはどこでも使用できるソリューションのようには見えません
Lu4

大丈夫です。次のような方が良いでしょう:function arrayOfSame(arr){return(arr.join( '')==(new Array(arr.length + 1).join(arr [0]))); }
Arkain 2017年

0

ES6の矢印関数構文を使用する場合のもう1つの興味深い方法:

x = ['a', 'a', 'a', 'a']
!x.filter(e=>e!==x[0])[0]  // true

x = ['a', 'a', 'b', 'a']
!x.filter(e=>e!==x[0])[0] // false

x = []
!x.filter(e=>e!==x[0])[0]  // true

そして、配列(x)の変数を再利用したくない場合:

!['a', 'a', 'a', 'a'].filter((e,i,a)=>e!==a[0])[0]    // true

array.every(...)を使用したIMOの以前のポスターには、最もクリーンなソリューションがあります。


0
function isUniform(array) {   
  for (var i=1; i< array.length; i++) {
    if (array[i] !== array[0]) { return false; }
  }

  for (var i=1; i< array.length; i++) {
    if (array[i] === array[0]) { return true; }
  }
}
  • 最初のループ。不均一を検出するたびに、「false」を返します
  • 最初のループが実行され、それがfalseを返した場合、「false」になります。
  • falseを返さない場合は、trueがあることを意味するため、2番目のループを実行します。そしてもちろん、2番目のループから「true」が返されます(最初のループでfalseではないことが判明したため)。

0

これはうまくいくかもしれませんが、コメントアウトコードを使用することもでき、指定されたscenerioでもうまく機能します。

function isUniform(){
	var arrayToMatch = [1,1,1,1,1];
	var temp = arrayToMatch[0];
	console.log(temp);
  /* return arrayToMatch.every(function(check){
    return check == temp;
   });*/
var bool;
   arrayToMatch.forEach(function(check){
    bool=(check == temp);
   })
  console.log(bool);
}
isUniform();


0

区切られたサイズと整理されたリストを使用する別の方法:

array1 = [1,2,3]; array2 = [1,2,3];

function isEqual(){

    return array1.toString()==array2.toString();
}

0

配列をセットに変換してサイズを確認できます

プリミティブ配列エントリの場合、つまりnumberstring

const isArrayWithEqualEntries = array => new Set(array).size === 1

等価性をテストするためにいくつかのフィールドを持つオブジェクトの配列の場合、次のように言いますid

const mapper = ({id}) => id
const isArrayWithEqualEntries = array => new Set(array.map(mapper)).size === 1

-4

PHPでは、非常にシンプルな1行の方法で解決策があります:

(count(array_count_values($ array))== 1)

例えば ​​:

$arr1 = ['a', 'a', 'a', 'a'];
$arr2 = ['a', 'a', 'b', 'a'];


print (count(array_count_values($arr1)) == 1 ? "identical" : "not identical"); // identical
print (count(array_count_values($arr2)) == 1 ? "identical" : "not identical"); // not identical

それで全部です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.