39

I have 3 values that I want to compare f, g and h. I have some code to check that they all equal each other and that none of them are null. I've had a look online but could not find anything that seemed to answer my query. Currently I am checking the code in the following way...

if(g == h && g == f && f == h && g != null && f != null && h != null)
{
//do something
}

This is quite long winded and I might be adding more values, so I was just wondering if there is a quicker way to check that none of the values are null and that all the values equal each other?

Thanks in advance for any help.

Phil
  • 1,610
  • 4
  • 26
  • 40
  • 1
    will you be ok with putting those values in an array? – Andreas Wong Apr 02 '12 at 08:49
  • You do not have to check all the variables if they are `!= null`.. If they are equal between them, you can check only one against `null`. The same with checking `f == h`.. if both `f` and `h` are equal to `g` you do not have to check those two .. – Gabriele Petrioli Apr 02 '12 at 08:50
  • have you compared the trade offs of putting all the var into an array? – cctan Apr 02 '12 at 08:50
  • If first three equations will be true then you must check only one variable to test if it is not null so: – Bartek Kobyłecki Apr 02 '12 at 08:51
  • Yes I could put them into an array, would it be easier to check them all if they were in an array? – Phil Apr 02 '12 at 08:54

7 Answers7

64

You could shorten that to

if(g === h && g === f && g !== null)
{
//do something
}

For an actual way to compare multiple values (regardless of their number)
(inspired by/ simplified @Rohan Prabhu answer)

function areEqual(){
   var len = arguments.length;
   for (var i = 1; i< len; i++){
      if (arguments[i] === null || arguments[i] !== arguments[i-1])
         return false;
   }
   return true;
}

and call this with

if( areEqual(a,b,c,d,e,f,g,h) )
{
//do something
}

And a more recent approach

function areEqualNotNull(values) {
  if (values[0] === null) return false;

  return values.every(value => value === values[0]);
}
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
35

What about

(new Set([a,b,c])).size === 1
olidem
  • 1,961
  • 2
  • 20
  • 45
  • 4
    That's definitely a very elegant solution that I'd never have considered. I wonder if it has any disadvantages. – Astridax Dec 12 '20 at 14:15
  • 2
    Nice solution! keep in mind, @Phil, that 1(Number) and "1"(String) will be treated as different values – Vlad R Mar 12 '21 at 06:32
  • Very elegant. The size property of Set returns the number of unique elements in a Set object. – Gene Myers Feb 13 '22 at 11:12
  • @Astridax disadvantages are that it allocates and garbage collects two objects (slow) and doesn't short circuit (also slow). But might be premature optimization not to use it if it's cleanest. – ggorlen May 14 '22 at 15:11
  • Also, OP says "none of them are null" but `new Set([null, null, null]).size === 1` is true, so this doesn't really fulfill the specification. That said, not being sure whether numbers are null probably indicates a deeper design problem. – ggorlen May 14 '22 at 15:16
20

Works for any number of items.

ES5

if ([f, g, h].every(function (v, i, a) {
  return (
    v === a[0] &&
    v !== null
  );
})) {
  // Do something
}

ES2015

if ([f, g, h].every((v, i, a) => 
  v === a[0] &&
  v !== null
)) {
  // Do something
}
JMM
  • 26,019
  • 3
  • 50
  • 55
5

I suggest you write a function where you give an array with all the values you want to compare and then iterate through the array to compare the values which each other:

function compareAllValues(a) {
     for (var i = 0; i < a.length; i++) {
         if (a[i] === null) { return false }
         for (var j = 0; j < i; j++) {
            if (a[j] !== a[i]) { return false }
         }
     }

     return true;
}

that should be it, I think :)

4

Write a simple function:

var checkAllArguments = function() {
    var len = arguments.length;
    var obj;

    if(len == 0) {
        return true;
    } else {
        if(arguments[0] == null) {
            return false;
        } else {
            obj = arguments[0];
        }
    }

    for(var i=1; i<len; i++) {
        if(arguments[i] == null) {
            return false;
        }

        if(obj == arguments[i]) {
            continue;
        } else {
            return false;
        }
    }

    return true;
}

Now, to check multiple arguments, all you have to do is:

if(checkAllArguments(g, h, f)) {
   // Do something
}
Rohan Prabhu
  • 7,180
  • 5
  • 37
  • 71
0

Create an array of string and check the existance of next value in there

compareAnswers(a1: string, a2: string, a3: string): boolean {
   this.compareAnswerArr.push(a1);
if (this.compareAnswerArr.includes(a2) == false) {
  this.compareAnswerArr.push(a2);
  if (this.compareAnswerArr.includes(a3) == false) {
    return true;
  } else return false;
}
else return false;}
Deepak Singla
  • 116
  • 1
  • 5
-2

Add a distinct function to Array.prototype:

Array.prototype.distinct = function() {
    var result = [];
    for(var i = 0; i < this.length; i++) {
        if (result.indexOf(this[i]) == -1) {
            result.push(this[i]);
        }
    }
    return result; 
}

Then do:

var myArray = [f, g, h];
if (myArray.indexOf(null) == -1 && myArray.unique().length == 1)
{
    // no nulls and all elements have the same value!
}
Kris
  • 40,604
  • 9
  • 72
  • 101
  • Note that I no longer recommend this – Kris Sep 19 '21 at 21:27
  • Thanks for the note, but if you no longer recommend it, consider [edit]ing it to something you do recommend or deleting it altogether. It's perfectly fine for answers to change as best practices move on. – ggorlen May 14 '22 at 15:14
  • You also have a typo: `unique()` rather than `distinct()`. Best to use `===` rather than `==`. – ggorlen May 14 '22 at 15:19