すべての値が等しい配列を見つける必要があります。これを行う最も速い方法は何ですか?ループして値を比較するだけですか?
['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false
a.join(',').split(a[0]).length === a.length + 1
すべての値が等しい配列を見つける必要があります。これを行う最も速い方法は何ですか?ループして値を比較するだけですか?
['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false
a.join(',').split(a[0]).length === a.length + 1
回答:
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()
メソッドは、配列内のすべての要素が、提供された関数によって実装されたテストに合格するかどうかをテストします。
const everythings_equal = array => array.every(thing => thing === array[0]);
some
代わりにevery
: arr.some( v => v !== arr[0] )
。これは、と等しくないことが判明した最初の要素で早期に戻りarr[0]
ます。
every
も早期に復帰します。
編集:赤い忍者になる:
!!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
最初に確認することをお勧めします。
false
s で構成されている場合、これは機能しません。たとえば、[false、false、false] .reduce(function(a、b){return(a === b)?a:false;});を試してください。
["false", ""]
リターンtrue
:/
NaN
。NaN === NaN
とNaN !== NaN
は両方ともfalseであるため、prev
がNaNに設定されると、値を取得できないことが保証されます。また、二重否定を追加するtrue
とfalse
、結果はandに変換されますNaN
。最終フォーム:!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
これは機能します。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
Array.prototype
(IE6でも)十分な拡張をサポートしています。一部の古いバージョンのIEが拡張をサポートしていないのは、DOM要素のプロトタイプのみです。
allValuesSame
と、ループに入ります
JavaScript 1.6では、以下を使用できますArray.every
。
function AllTheSame(array) {
var first = array[0];
return array.every(function(element) {
return element === first;
});
}
おそらく配列に要素がない場合など、おそらくいくつかの健全性チェックが必要です。(また、すべての要素がNaN
以降の場合、これは機能NaN !== NaN
しませんが、それは問題ではありません...よろしいですか?)
配列をセットに変えることができます。セットのサイズが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
に注意してください。
また、パフォーマンスの比較のためにベンチマークも行いました。
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()を使用することが、サンプリングされたメソッドの中で最も速い方法です。
Array#some
ときどきパフォーマンスが向上する理由は、コールバック関数がtrueを返すと、反復が停止するためです。したがって、すべての要素が実際に等しい場合、パフォーマンスはと同じになりArray#every
ます。また、すべての要素が等しくない場合の相対的なパフォーマンスは、最初の一致しない要素のインデックスによって異なります。
アンダースコア/ロダッシュを使用した最短の回答
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
すでに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
だけで十分です。
はい、次のようにフィルターを使用して確認することもできます。非常に単純で、すべての値を確認することは最初の値と同じです。
//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
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になります:)
some
なく、代わりに使用しevery
ました。:)キャッチをありがとう!
新しいソリューションを更新:インデックスを確認
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));
}
Underscoreの_.isEqual(object, other)
機能は、配列に対してうまく機能するようです。配列内のアイテムの順序は、等しいかどうかを確認するときに重要です。http://underscorejs.org/#isEqualを参照してください。
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);
}));
}
それは簡単です。関数を作成し、パラメーターを渡します。その関数で、最初のインデックスを新しい変数にコピーします。次に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;
}
受け入れ答えは素晴らしい仕事が、私はほんの少しを追加したいです。===
オブジェクトの配列の配列を比較していたため、使用できませんでしたが、アプリ全体で、私が強く推奨する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
}
]
]
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']));
これで完了です。
まあ、これは本当にそれほど複雑ではありません。あなたも試さなかった強い疑いがあります。最初の値を選択して変数に保存し、for
ループ内で後続のすべての値を最初の値と比較します。
私は意図的にコードを共有しませんでした。がどのようfor
に使用され、どのように変数が比較されるかを見つけます。
単純な1行のソリューション。最初のエントリで満たされた配列と比較するだけです。
if(arr.join('') === Array(arr.length).fill(arr[0]).join(''))
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の以前のポスターには、最もクリーンなソリューションがあります。
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; }
}
}
これはうまくいくかもしれませんが、コメントアウトコードを使用することもでき、指定された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();
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
それで全部です。