检查数组的所有值是否相等

Mar*_*in3 157 javascript jquery

我需要找到所有值相等的数组.最快的方法是什么?我应该遍历它并只是比较值吗?

['a', 'a', 'a', 'a'] // true
['a', 'a', 'b', 'a'] // false
Run Code Online (Sandbox Code Playgroud)

gol*_*pot 219

const allEqual = arr => arr.every( v => v === arr[0] )
allEqual( [1,1,1,1] )  // true
Run Code Online (Sandbox Code Playgroud)

或者单行:

[1,1,1,1].every( (val, i, arr) => val === arr[0] )   // true
Run Code Online (Sandbox Code Playgroud)

Array.prototype.every(来自MDN):该every()方法测试数组中的所有元素是否都通过了由提供的函数实现的测试.

  • 简洁是机智的灵魂 (7认同)
  • @Jan `every` 也会提前返回。 (7认同)
  • 注意:如果数组为空,此解决方案也将返回 true! (5认同)
  • @MaximZubalev 好吧,在这种情况下所有元素*都是*相等的。 (3认同)
  • `const everythings_equal = array => array.every(thing => thing === array[0]);` (2认同)
  • 使用`some`代替`every`:`arr.some(v => v!== arr [0])。这将在发现第一个元素不等于arr [0]时返回。 (2认同)

Mar*_*tin 111

编辑:成为红色忍者:

!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
Run Code Online (Sandbox Code Playgroud)

结果:

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" 
Run Code Online (Sandbox Code Playgroud)

警告:

var array = [] => result: TypeError thrown
Run Code Online (Sandbox Code Playgroud)

这是因为我们没有传递initialValue.所以,您可能希望先检查一下array.length.

  • 这可以通过使用"NaN"来达到一个档次.因为'NaN === NaN`和`NaN!== NaN`都是假的,所以它保证一旦`prev`设置为NaN,那么没有值可以取出它.同时添加双重否定将结果转换为"true"和"false",因为"NaN"是假的.最终形式:`!! array.reduce(function(a,b){return(a === b)?a:NaN;});` (6认同)
  • 派对可能有点晚了...我认为如果你的阵列是由`false`s制成的话,这不行!例如,尝试[false,false,false] .reduce(function(a,b){return(a === b)?a:false;}); (4认同)
  • @Martin:`["false",""]`返回`true`:/ (3认同)
  • ****DOWNVOTED.如果元素相等但**_ falsy _**怎么办? (3认同)
  • 我贬低了因为这不适用于布尔值. (3认同)

Rob*_*cke 62

这有效.您可以使用原型在Array上创建方法.

Array.prototype.allValuesSame = function() {

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

    return true;
}
Run Code Online (Sandbox Code Playgroud)

以这种方式调用它:

var a = ['a', 'a', 'a'];
var b = a.allValuesSame(); //true
a = ['a', 'b', 'a'];
b = a.allValuesSame(); //false
Run Code Online (Sandbox Code Playgroud)

  • @TomášZato:IE支持扩充`Array.prototype`就好(甚至是IE6).它只是DOM元素原型,一些旧版本的IE不支持扩充. (5认同)
  • 非常好,但要注意:IE不支持这种分配原型的方式.无论如何我用它. (4认同)
  • 我不认为猴子修补内置原型是个好主意.如果多个库执行此操作,则可能导致难以调试的意外行为. (3认同)

Mat*_*ens 30

在JavaScript 1.6中,您可以使用Array.every:

function AllTheSame(array) {
    var first = array[0];
    return array.every(function(element) {
        return element === first;
    });
}
Run Code Online (Sandbox Code Playgroud)

您可能需要一些健全性检查,例如,当阵列没有元素时.(此外,NaN从那以后所有元素都不起作用NaN !== NaN,但这应该不是问题......对吗?)


Huy*_*ran 26

您可以将Array转换为Set.如果Set的大小等于1,则Array的所有元素都相等.

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

allEqual(['a', 'a', 'a', 'a']); // true
allEqual(['a', 'a', 'b', 'a']); // false
Run Code Online (Sandbox Code Playgroud)

  • **很棒。** 请注意,在这种情况下,`allEqual([NaN, NaN])` 给出了 `true`。 (2认同)

Kai*_*Kai 14

更新2022版本:使用Set()

     let a = ['a', 'a', 'b', 'a'];
     let b = ['a', 'a', 'a', 'a'];
     const check = (list) => {
        const setItem = new Set(list);
        return setItem.size <= 1;
     }

     const checkShort = (list) => (new Set(list)).size <= 1        
     
      check(a); // false;
      check(b); // true;
      checkShort(a); // false
      checkShort(b); // true
Run Code Online (Sandbox Code Playgroud)

更新新解决方案:检查索引

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

使用 ES6 更新:使用list.every是最快的方法:

 let a = ['a', 'a', 'b', 'a'];
 let check = (list) => list.every(item => item === list[0]);
   
Run Code Online (Sandbox Code Playgroud)

旧版本:

      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));
      }
Run Code Online (Sandbox Code Playgroud)


Mar*_*tin 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];
    });
}
Run Code Online (Sandbox Code Playgroud)

结果:

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)
Run Code Online (Sandbox Code Playgroud)

所以显然使用内置的array.some()是采样的最快方法.

  • 最好检查一下这里的性能更高."Array#some"有时会胜过的原因是,一旦回调函数返回true,它就会停止迭代.因此,如果所有元素实际上相等,则性能应与"Array#every"相同.并且当所有元素不相等时的相对性能将基于第一非匹配元素的索引而变化. (3认同)
  • 好东西。您可能已经使用lol命名了每个函数。例如:减少,过滤,每个,一些 (2认同)

ave*_*Joe 8

使用下划线/ lodash的最短答案

function elementsEqual(arr) {
    return !_.without(arr, arr[0]).length
}
Run Code Online (Sandbox Code Playgroud)

规格:

elementsEqual(null) // throws error
elementsEqual([]) // true
elementsEqual({}) // true
elementsEqual([1]) // true
elementsEqual([1,2]) // false
elementsEqual(NaN) // true
Run Code Online (Sandbox Code Playgroud)

编辑:

或者更短,受汤姆答案的启发:

function elementsEqual2(arr) {
    return _.uniq(arr).length <= 1;
}
Run Code Online (Sandbox Code Playgroud)

规格:

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


小智 8

every() 函数检查数组中是否有所有元素

    const checkArr = a => a.every( val => val === a[0] )
    checkArr(['a','a','a'])  // true 
     
Run Code Online (Sandbox Code Playgroud)


Tom*_*ech 6

如果您已经在使用underscore.js,那么这里有另一个选项_.uniq:

function allEqual(arr) {
    return _.uniq(arr).length === 1;
}
Run Code Online (Sandbox Code Playgroud)

_.uniq返回数组的无副本版本.如果所有值都相同,则长度将为1.

正如评论中所提到的,假设您可能希望返回一个空数组true,那么您还应检查该情况:

function allEqual(arr) {
    return arr.length === 0 || _.uniq(arr).length === 1;
}
Run Code Online (Sandbox Code Playgroud)


Ali*_*eza 6

是的,你可以使用过滤器检查它,如下所示,非常简单,检查每个值是否与第一个相同:

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

也可以使用数组上的每个方法完成:

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

你可以检查你的数组如下:

sameValues(['a', 'a', 'a', 'a']); // true
sameValues(['a', 'a', 'b', 'a']); // false
Run Code Online (Sandbox Code Playgroud)

或者,如果您重复使用它,可以将其添加到JavaScript中的本机Array功能:

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

你可以检查你的数组如下:

['a', 'a', 'a', 'a'].sameValues(); // true
['a', 'a', 'b', 'a'].sameValues(); // false
Run Code Online (Sandbox Code Playgroud)


Kri*_* PC 6

现在您可以使用集合轻松地做到这一点。

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);
Run Code Online (Sandbox Code Playgroud)


ZER*_*ER0 5

Array.every如果支持,可以使用:

var equals = array.every(function(value, index, array){
    return value === array[0];
});
Run Code Online (Sandbox Code Playgroud)

循环的替代方法可能类似于 sort

var temp = array.slice(0).sort();
var equals = temp[0] === temp[temp.length - 1];
Run Code Online (Sandbox Code Playgroud)

或者,如果这些项目像问题一样,则有些肮脏,例如:

var equals = array.join('').split(array[0]).join('').length === 0;
Run Code Online (Sandbox Code Playgroud)

也可以。


Noo*_*oor 5

你可以使用Array.prototype.everyObject.is和 ES6 箭头函数让这个单行代码做你想做的事:

const all = arr => arr.every(x => Object.is(arr[0], x));
Run Code Online (Sandbox Code Playgroud)

  • 请描述您提出的解决方案。 (2认同)