4

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
  }
));
caramba
  • 21,963
  • 19
  • 86
  • 127

3 Answers3

8

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
));
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Thank you T.J. as usual your explanation is fantastic! – caramba Jan 10 '17 at 10:19
  • @MichałPerłakowski: That depends on what result you want from an empty array. `every` always returned `true` for empty arrays. Whether that's right or wrong depends on the use case. – T.J. Crowder Sep 03 '17 at 13:50
1

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.

Redu
  • 25,060
  • 6
  • 56
  • 76
-1

try (if they are numeric) this way

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

var same = myArray1 >= myArray2 && myArray1 <= myArray2;
Romko
  • 1,808
  • 21
  • 27
  • I see three possible reasons: 1. The question is about checking if all the values in a single array are the same. The above is comparing `myArray1` to `myArray2` instead. 2. Comparing arrays by converting them to strings and then doing a lexicographic comparison is not a great idea. 3. `a >= b && a <= b` is a long-winded way to write `a == b`. – T.J. Crowder Jan 10 '17 at 10:14
  • @T.J.Crowder, nope! a == b compares references and in my case i'm comparing arrays element by element, so you are not right. – Romko Jan 10 '17 at 10:16
  • Yes, `==` with arrays would compare references. But rather than converting both arrays to strings **twice**, the right way to do it lexicographically (which isn't the right way to do it) is `var same = String(myArray1) == String(myArray2);` (or `var same = myArray1.join() == myArray2.join()` or similar). – T.J. Crowder Jan 10 '17 at 10:19
  • @T.J.Crowder, agree on this, but my answer doesnt deserve downvotes (is this from your side?), it works so i cannot see any reason it's wrong. – Romko Jan 10 '17 at 10:22
  • It's wrong because it's answering a question the OP didn't ask, as I pointed out above. It's also promoting poor practice (comparing arrays lexicographically). Also: Please don't fall into the trap of believing the people voting are the same people as the people commenting. You'll be wrong much more often than you're right. Just take votes as an indication something's wrong, that's what they mean. – T.J. Crowder Jan 10 '17 at 10:22
  • @T.J.Crowder, OP asked about reduce, so your answer isn't correct in this case also :), anyway it's correct, so I think it answers the question, even if it is not the way OP asked. – Romko Jan 10 '17 at 10:27
  • Hmmm, have you read the second half of my answer? But again: You're answering a question **the OP didn't ask**. He didn't ask about comparing `myArray1` to `myArray2`. Why be so married to a patently-incorrect answer? Delete and move on. That's what I do when I get it wrong, as everyone does sometimes. Yeesh. – T.J. Crowder Jan 10 '17 at 10:28
  • @T.J.Crowder, i don't say it was you, i just assumed, if it wasn't you, i appeciate it. and if you say it is incorrect, it's only yours (and downvoter's) thoughts. – Romko Jan 10 '17 at 10:29
  • 1
    @Romko thank you for your time and effort. But it is really not what I was looking for or trying to do. – caramba Jan 10 '17 at 10:55