Marvin3
Marvin3

Reputation: 6041

Check if all values of array are equal

I need to find arrays where all values are equal. What's the fastest way to do this? Should I loop through it and just compare values?

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

Upvotes: 343

Views: 558461

Answers (30)

Baraja Swargiary
Baraja Swargiary

Reputation: 449

Use index of operator for every item of array to check if it exists or not. If even one item returns -1 (doesn't exist then it will be false)

const arr1 = [1, 3, 5];
const arr2 = [5, 7, 9];
const arr3 = [1, 3, 5];

arr1.every(item => arr2.indexOf(item) != -1)
// this will return false

arr1.every(item => arr3.indexOf(item) != -1)
// this will return true

Upvotes: 0

Kai
Kai

Reputation: 3653

update 2022 version: use 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

Update new solution: check index

 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;
   

Updated with ES6: Use list.every is the fastest way:

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

old version:

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

Upvotes: 16

aminben slimen
aminben slimen

Reputation: 71

another cool solution i like is using XOR operator :

console.log([5,5,5,5].reduce((a,b)=>a^b) == 0)
>> true
console.log([5,5,5,4].reduce((a,b)=>a^b) == 0)
>> false

Upvotes: -2

Ignacio Soria
Ignacio Soria

Reputation: 1

You could count the number of distinct values in the array, if this value is 1 all the entries are the same.

Example:

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

Upvotes: -1

Dilip Kumar Choudhary
Dilip Kumar Choudhary

Reputation: 469

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

Upvotes: -1

Ashish Mishra
Ashish Mishra

Reputation: 422

every() function check if all elements of an array

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

Upvotes: 9

Armando Guarino
Armando Guarino

Reputation: 1621

You could use a for loop:

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

Upvotes: 2

Simon
Simon

Reputation: 177

You can convert array to a Set and check its size

In case of primitive array entries, i.e. number, string:

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

In case of array of objects with some field to be tested for equivalence, say id:

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

Upvotes: 3

Martin
Martin

Reputation: 3592

Edit: Be a Red ninja:

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

Results:

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" 

Warning:

var array = [] => result: TypeError thrown

This is because we do not pass an initialValue. So, you may wish to check array.length first.

Upvotes: 116

Robert Fricke
Robert Fricke

Reputation: 3643

This works. You create a method on Array by using prototype.

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

Call this in this way:

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

Upvotes: 64

Krishnadas PC
Krishnadas PC

Reputation: 6519

Now you can make use of sets to do that easily.

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

Upvotes: 6

Rahul Vala
Rahul Vala

Reputation: 715

  1. Create a string by joining the array.
  2. Create string by repetition of the first character of the given array
  3. match both strings

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

And you are DONE !

Upvotes: 1

Michael Aaron Wilson
Michael Aaron Wilson

Reputation: 1030

The accepted answer worked great but I wanted to add a tiny bit. It didn't work for me to use === because I was comparing arrays of arrays of objects, however throughout my app I've been using the fast-deep-equal package which I highly recommend. With that, my code looks like this:

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

and my data looks like this:

[  
  [
    {
      "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
    }
  ]
]

Upvotes: 2

Chiawen
Chiawen

Reputation: 11759

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

Or one-liner:

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

Array.prototype.every (from MDN) : The every() method tests whether all elements in the array pass the test implemented by the provided function.

Upvotes: 561

Alireza
Alireza

Reputation: 104650

Yes, you can check it also using filter as below, very simple, checking every values are the same as the first one:

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

also can be done using every method on the array:

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

and you can check your arrays like below:

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

Or you can add it to native Array functionalities in JavaScript if you reuse it a lot:

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

and you can check your arrays like below:

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

Upvotes: 6

Huy Tran
Huy Tran

Reputation: 1902

You can turn the Array into a Set. If the size of the Set is equal to 1, then all elements of the Array are equal.

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

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

Upvotes: 77

Aman Pathak
Aman Pathak

Reputation: 1

this might work , you can use the comment out code as well that also woks well with the given 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();

Upvotes: 0

Jaden Tran
Jaden Tran

Reputation: 13

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; }
  }
}
  • For the first loop; whenever it detects uneven, returns "false"
  • The first loop runs, and if it returns false, we have "false"
  • When it's not return false, it means there will be true, so we do the second loop. And of course we will have "true" from the second loop (because the first loop found it's NOT false)

Upvotes: 1

Tomasz Szawara
Tomasz Szawara

Reputation: 87

Another interesting way when you use ES6 arrow function syntax:

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

And when you don't want to reuse the variable for array (x):

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

IMO previous poster who used array.every(...) has the cleanest solution.

Upvotes: 0

average Joe
average Joe

Reputation: 4595

Shortest answer using underscore/lodash

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

spec:

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

edit:

Or even shorter, inspired by Tom's answer:

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

spec:

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

Upvotes: 10

Jerry
Jerry

Reputation: 1238

In PHP, there is a solution very simple, one line method :

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

For example :

$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

That's all.

Upvotes: -5

Adithya Santhosh
Adithya Santhosh

Reputation: 54

Its Simple. Create a function and pass a parameter. In that function copy the first index into a new variable. Then Create a for loop and loop through the array. Inside a loop create an while loop with a condition checking whether the new created variable is equal to all the elements in the loop. if its equal return true after the for loop completes else return false inside the while loop.

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

Upvotes: 2

Tom Fenech
Tom Fenech

Reputation: 74595

If you're already using underscore.js, then here's another option using _.uniq:

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

_.uniq returns a duplicate-free version of the array. If all the values are the same, then the length will be 1.

As mentioned in the comments, given that you may expect an empty array to return true, then you should also check for that case:

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

Upvotes: 10

pyviet
pyviet

Reputation: 9

Simple one line solution, just compare it to an array filled with the first entry.

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

Upvotes: -1

Noor
Noor

Reputation: 191

You can get this one-liner to do what you want using Array.prototype.every, Object.is, and ES6 arrow functions:

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

Upvotes: 5

ZER0
ZER0

Reputation: 25322

You can use Array.every if supported:

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

Alternatives approach of a loop could be something like sort

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

Or, if the items are like the question, something dirty like:

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

Also works.

Upvotes: 7

user4861889
user4861889

Reputation: 11

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

Upvotes: 1

Martin
Martin

Reputation: 3592

arr.length && arr.reduce(function(a, b){return (a === b)?a:false;}) === arr[0];

Upvotes: 2

Nicholas
Nicholas

Reputation: 41

I think the simplest way to do this is to create a loop to compare the each value to the next. As long as there is a break in the "chain" then it would return false. If the first is equal to the second, the second equal to the third and so on, then we can conclude that all elements of the array are equal to each other.

given an array data[], then you can use:

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

Upvotes: 4

Martin
Martin

Reputation: 3592

And for performance comparison I also did a benchmark:

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

Results:

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)

So apparently using builtin array.some() is the fastest method of the ones sampled.

Upvotes: 17

Related Questions