【问题标题】:Check if all values of array are equal检查数组的所有值是否相等
【发布时间】:2013-01-27 18:18:03
【问题描述】:

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

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

【问题讨论】:

  • @T.J.Crowder 我敢打赌你已经在考虑最好的解决方案了;)
  • @T.J.Crowder:更不用说提问者愿意实际接受答案了。最近,拥有 1 个代表的用户似乎经常被询问和运行类型,一旦他们得到可复制粘贴的答案就会离开。
  • 这种方法应该可行吗? a.join(',').split(a[0]).length === a.length + 1
  • @TomášZato:“OP”的意思是“原始发帖人”(提出问题的人)。

标签: javascript jquery


【解决方案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 代替everyarr.some( v => v !== arr[0] )。这将在发现不等于 arr[0] 的第一个元素时尽早返回。
  • @Jan every 也会提前返回。
  • 注意:如果数组为空,此解决方案也将返回 true!
【解决方案2】:

编辑:成为红色忍者:

!!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

【讨论】:

  • 聚会可能有点晚了...我认为如果您的阵列由falses 组成,这将不起作用!例如尝试 [false, false, false].reduce(function(a, b){return (a === b)?a:false;});
  • @Martin: ["false", ""] 返回 true :/
  • 这可以通过使用NaN 来提高。因为NaN === NaNNaN !== NaN 都是假的,所以它保证一旦prev 设置为NaN,那么没有值可以取出它。同样添加双重否定会将结果转换为truefalse,因为NaN 是虚假的。最终形式:!!array.reduce(function(a, b){ return (a === b) ? a : NaN; });
  • 否决。如果元素相等但 falsy 怎么办?
  • 我投了反对票,因为这不适用于布尔值。
【解决方案3】:

这行得通。您可以使用原型在 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

【讨论】:

  • 非常好,但要注意:IE 不支持这种分配原型的方式。我还是用它。
  • @TomášZato:IE 支持扩展 Array.prototype 就好了(甚至 IE6)。一些旧版本的 IE 不支持扩充的只是 DOM 元素原型。
  • 我认为猴子修补内置原型并不是一个好主意。如果多个库都这样做,可能会导致难以调试的意外行为。
  • @MarkWilbur +1 特别是如果你在下一个数组上执行 for..in 循环,你会在循环中得到 allValuesSame
  • 我继续进行了现代化改造,但没有改变意图。
【解决方案4】:

你可以把数组变成一个集合。如果 Set 的大小等于 1,则 Array 的所有元素都相等。

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
  • ^ 因为NaN === NaNNaN == NaN 都计算为false
【解决方案5】:

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

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

您可能需要进行一些健全性检查,例如当数组没有元素时。 (另外,当所有元素都是NaN 时,这将不起作用,因为NaN !== NaN,但这不应该是一个问题......对吧?)

【讨论】:

    【解决方案6】:

    为了进行性能比较,我还做了一个基准测试:

    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 相同。并且所有元素不相等时的相对性能将根据第一个不匹配元素的索引而有所不同。
    • 不错的一个。您可以使用使用的函数命名每个 lol。例如:减少、过滤、每个、一些
    • 原生 for 循环在哪里,我敢打赌它的性能比所有这些都要高 5 倍
    【解决方案7】:

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

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

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

    如 cmets 中所述,鉴于您可能期望一个空数组返回 true,那么您还应该检查这种情况:

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

    【讨论】:

    • 但是如果数组为空,你的答案将返回false。虽然我认为应该是true。不过改成.length &lt;= 1就够了。
    • @Kasztan 这是一个公平的观点。我已经更新了我的答案以涵盖该案例。
    【解决方案8】:

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

    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
    

    【讨论】:

      【解决方案9】:

      every() 函数检查数组的所有元素

          const checkArr = a => a.every( val => val === a[0] )
          checkArr(['a','a','a'])  // true 
           
      

      【讨论】:

        【解决方案10】:

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

        //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
        

        【讨论】:

          【解决方案11】:

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

           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;
             
          

          使用 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));
                }
          

          【讨论】:

            【解决方案12】:

            如果支持,您可以使用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) =&gt; v!==a[0] )。否则,您只是检查任何值是否等于第一个值,当然,这将始终为真 :)
            • 不完全是,我使用了some 而不是我在第一段中提到的every。 :) 谢谢你的收获!
            【解决方案13】:

            您可以使用 Array.prototype.everyObject.is 和 ES6 箭头函数让这个单线执行您想要的操作:

            const all = arr => arr.every(x => Object.is(arr[0], x));
            

            【讨论】:

            • 请描述您提出的解决方案。
            【解决方案14】:

            我认为最简单的方法是创建一个循环来将每个值与下一个值进行比较。只要“链”中有中断,它就会返回假。如果第一个等于第二个,第二个等于第三个,以此类推,那么我们可以得出结论,数组的所有元素都彼此相等。

            给定一个数组data[],那么你可以使用:

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

            【讨论】:

              【解决方案15】:

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

              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);

              【讨论】:

                【解决方案16】:
                arr.length && arr.reduce(function(a, b){return (a === b)?a:false;}) === arr[0];
                

                【讨论】:

                  【解决方案17】:

                  你可以用这个:

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

                  函数首先检查数组是否为空。如果是它的值是相等的.. 否则,它会过滤数组并获取与第一个不同的所有元素。如果没有这样的值 => 数组只包含相等的元素,否则它不包含。

                  【讨论】:

                    【解决方案18】:

                    很简单。 创建一个函数并传递一个参数。 在该函数中,将第一个索引复制到一个新变量中。 然后创建一个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;
                    }
                    

                    【讨论】:

                      【解决方案19】:

                      accepted answer 效果很好,但我想补充一点。使用=== 对我不起作用,因为我正在比较对象数组的数组,但是在我的应用程序中,我一直在使用我强烈推荐的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
                          }
                        ]
                      ]
                      

                      【讨论】:

                        【解决方案20】:

                        您可以将数组转换为 Set 并检查其大小

                        如果是原始数组条目,即numberstring

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

                        如果对象数组具有要测试等效性的某些字段,例如id

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

                        【讨论】:

                          【解决方案21】:

                          你可以使用 for 循环:

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

                          【讨论】:

                            【解决方案22】:

                            Underscore 的_.isEqual(object, other) 函数似乎适用于数组。数组中项目的顺序在检查是否相等时很重要。见http://underscorejs.org/#isEqual

                            【讨论】:

                              【解决方案23】:
                              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);
                                  }));
                              }
                              

                              【讨论】:

                              • 请解释一下你做了什么,而不是仅仅粘贴一些代码。
                              【解决方案24】:
                              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,所以我们进行第二个循环。当然,我们将从第二个循环中得到“真”(因为第一个循环发现它不是假的)

                              【讨论】:

                                【解决方案25】:

                                另一种使用 ES6 箭头函数语法的有趣方式:

                                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 以前的海报有最干净的解决方案。

                                【讨论】:

                                  【解决方案26】:

                                  这可能有效,您也可以使用注释掉代码,它也适用于给定的场景。

                                  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();

                                  【讨论】:

                                    【解决方案27】:
                                    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']));

                                    你已经完成了!

                                    【讨论】:

                                      【解决方案28】:

                                      简单的一行解决方案,只需将其与填充第一个条目的数组进行比较。

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

                                      【讨论】:

                                      • 这似乎不是一个可以在任何地方使用的解决方案
                                      • 已经差不多了。更好的是: function arrayOfSame(arr) { return (arr.join('') == (new Array(arr.length+1).join(arr[0]))); }
                                      【解决方案29】:
                                      **// Logical Solution:- Declare global array and one variable(To check the condition) whether all element of an array contains same value or not.**
                                      
                                          var arr =[];
                                          var isMatching = false;
                                      
                                          for(var i=0;i<arr.length;i++){
                                                  if(String(arr[i]).toLowerCase()== "Your string to check"){
                                                      isMatching=true;
                                                      // Array has same value in all index of an array
                                                  }
                                                  else{
                                                      isMatching=false;
                                                      // Array Doesn't has same value in all index of an array
                                                      break;
                                                  }
                                              }
                                          // **Check isMatching variable is true or false**
                                      
                                              if(isMatching){ // True
                                                  //If Array has same value in all index, then this block will get executed
                                              }
                                              else{ //False
                                                  //If Array doesn't has same value in all index, then this block will get executed
                                              }
                                      

                                      【讨论】:

                                        【解决方案30】:

                                        您可以计算数组中不同值的数量,如果该值为 1,则所有条目都相同。

                                        例子:

                                        array = np.array([1, 2, 2, 3, 3])
                                        set(array) # this gives the different values present in the array (1,2,3)
                                        len(set(array)) # this returns 3, 3 different values in the array
                                        

                                        【讨论】:

                                          猜你喜欢
                                          • 2015-02-12
                                          • 2018-05-13
                                          • 1970-01-01
                                          • 2014-12-27
                                          • 2012-05-20
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          • 1970-01-01
                                          相关资源
                                          最近更新 更多