Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if all array values are the same with reduce()

I need to compare all values in ONE array to know if they're all equal or not. So this works fine and gives me the expected output

var myArray1 = [50, 50, 50, 50, 50];  // all values are same, should return true
var myArray2 = [50, 50, 50, 50, 51];  // last value differs, should return false

function compare(array) {
    var isSame = true;
    for(var i=0; i < array.length; i++) {
       isSame = array[0] === array[i] ? true : false;
    }
    return isSame;
}

console.log('compare 1:', compare(myArray1)); // true 
console.log('compare 2:', compare(myArray2)); // false

Then I've tried the same with reduce() but looks like I'm misunderstanding that function. They both say it is false. Am I doing something obviously wrong? Can I use reduce() to get what I need? If so how?

var myArray1 = [50, 50, 50, 50, 50];
var myArray2 = [50, 50, 50, 50, 51];

console.log('reduce 1:', myArray1.reduce(
  function(a, b){
    return a === b ? true : false
  }
));

console.log('reduce 2:', myArray2.reduce(
  function(a, b){
    return a === b ? true : false
  }
));
like image 209
caramba Avatar asked Feb 05 '23 08:02

caramba


2 Answers

reduce just isn't the right tool here, the value you return from one iteration is used as a in the next iteration, and reduce doesn't short-circuit.

If you want to use one of the array methods to do this, every would be a reasonable choice:

var myArray1 = [50, 50, 50, 50, 50];
var myArray2 = [50, 50, 50, 50, 51];

console.log('some 1:', myArray1.every(
  function(value, _, array){
    return array[0] === value;
  }
));

console.log('some 2:', myArray2.every(
  function(value, _, array){
    return array[0] === value;
  }
));

every short-circuits, stopping as soon as the result is known.

I mean, you could shoe-horn it into a reduce, but it's not appropriate. We initialize the flag with true and then propagate the result of &&'ing it with checking that entry against the array's first entry:

var myArray1 = [50, 50, 50, 50, 50];
var myArray2 = [50, 50, 50, 50, 51];

console.log('some 1:', myArray1.reduce(
  function(flag, value){
    return flag && myArray1[0] === value;
  },
  true
));

console.log('some 2:', myArray2.reduce(
  function(flag, value){
    return flag && myArray2[0] === value;
  },
  true
));
like image 99
T.J. Crowder Avatar answered Feb 08 '23 12:02

T.J. Crowder


The normal way is to use the .every() functor. If insisted i would come up with a .reduce() solution as follows;

var arr = [50,50,50,50,50],
    brr = [50,50,51,50,50],
    res = arr.reduce((p,c) => p === c ? p : false);
console.log(res);
res = brr.reduce((p,c) => p === c ? p : false);
console.log(res);

It will return the element that's the array is filled with or false if there is a black sheep. The above code will fail if your input array is full of falses.

like image 44
Redu Avatar answered Feb 08 '23 12:02

Redu