Compare Three Values for Equality

Compare three values for equality

You can use the power of tuples and the Transitive Property of Equality.

if (number1, number2) == (number2, number3) {

}

The clause of this IF is true only when number1 is equals to number2 AND number2 is equals to number3. It means that the 3 values must be equals.

Comparing 3 identical values for equality using Javascript

To check whether all three variables are equal or not, use && operator to add on queries.

&& returns true if all conditions are true.

function equal(a,b,c){
return a == b && b == c;
}

As mentioned by @mplungjan, for strict comparison use === instead of ==.

How do I check the equality of three values elegantly?

A note beforehand:

Your last proposed solution is the shortest, clearest and most efficient way to compare if 3 values are equal:

if a == b && a == c {
fmt.Println("Clearest: all 3 are equal")
}

or alternatively (to your liking):

if a == b && b == c {
fmt.Println("Clearest: all 3 are equal")
}

The rest of this answer (what follows) is just toying with the language specification and the language's capabilities, presenting what I find fun and creative. They do not attempt to provide a superior solution.


Try all the examples below on the Go Playground. The examples build on the terms and the result of the comparisons which are defined in Spec: Comparison operators.

General note: in the examples below I used the type interface{} which will work whatever type your values have (a, b and c), but if you know they are of type int for example, you can use that specific type too (which would improve efficiency and shorten the length of the examples).

With a map as a set

if len(map[interface{}]int{a: 0, b: 0, c: 0}) == 1 {
fmt.Println("Map set: all 3 are equal")
}

Effectively we put all comparable values into a map as keys, and if all are equal, there will be only 1 pair in the map, so the "length" of the map will be 1. The value type of the map doesn't play any role here, it could be anything. I used int because this results in the shortest composite literal (that defines the map value).

This solution is flexible as you can use any number of values to test if all are equal, not just 3.

With arrays

Arrays are comparable (unlike slices):

if [2]interface{}{a, b} == [2]interface{}{b, c} {
fmt.Println("Arrays: all 3 are equal")
}

The result of the array comparison will be true if a == b and b == c (if the corresponding elements are equal).

Note that you can apply this method on any number of values as well. It would look like this for 5 values:

if [4]interface{}{a, b, c, d} == [4]interface{}{b, c, d, e} {
fmt.Println("Arrays: all 5 are equal")
}

With a tricky map

if map[interface{}]bool{a: b == c}[b] {
fmt.Println("Tricky map: all 3 are equal")
}

This composite literal will assign the comparision result of b == c to the key a. And we ask the value associated with the key b. If a == b, the result of the indexing expression will be the result of b == c, that is, whether all 3 values are equal. If a != b, then the zero value of the value type will be the result, which is false in case of bool, properly telling that all 3 values are not equal.

With anonymous structs

struct values are also comparable, so:

if struct{ a, b interface{} }{a, b} == struct{ a, b interface{} }{b, c} {
fmt.Println("Anon structs: all 3 are equal")
}

With (named) structs

If we define a simple struct beforehand:

type P struct{ a, b interface{} }

Comparison will be much more compact:

if (P{a, b} == P{b, c}) {
fmt.Println("Structs: all 3 are equal")
}

(Note that the expression of the if statement must be put in parenthesis to avoid parsing ambiguity - else it's a compile time error!)

With slices

Slices are not comparable, so we will need to borrow some help from reflect.DeepEqual():

if reflect.DeepEqual([]interface{}{a, b}, []interface{}{b, c}) {
fmt.Println("Slices: all 3 are equal")
}

With a helper function

func AllEquals(v ...interface{}) bool {
if len(v) > 1 {
a := v[0]
for _, s := range v {
if a != s {
return false
}
}
}
return true
}

And using it:

if AllEquals(a, b, c) {
fmt.Println("Helper function: all 3 are equal")
}

This solution is also flexible, you can call AllEquals() with any number of values.

Note that we can make the AllEquals() function more compact if we're also willing to call reflect.DeepEqual() here:

func AllEquals2(v ...interface{}) bool {
if len(v) < 2 {
return true
}
return reflect.DeepEqual(v[:len(v)-1], v[1:])
}

alternative way to compare if three ints are equal

Equality is transitive; you don't need the last comparison b == c. If a == b and a == c, then b == c.

Try

if ((a == b) && (a == c)){

Why comparing three variables together with == evaluates to false?

This is because of the way expression and types are evaluated.

Let's evaluate the leftmost ==

x == y ...

This evaluates to true. Let's rewrite the expression:

//  x == y
if (true == z) {
// ...
}

The true is a boolean value. A boolean value cannot be directly compared to an int. A conversion from the boolean to an integer must occur, and the result is 1 (yes, true == 1). Let's rewrite the expression to its equivalent value:

//  true
if (1 == z) {
// ^--- that's false
}

But z isn't equal to 1. That expression is false!

Instead, you should separate both boolean expressions:

if (x == y && y == z) {
// ...
}

Javascript compare 3 values

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
}

Testing equality of three values

Python chains such relational operators naturally (including in and is).

a() == b() == c() is functionally equivalent to a() == b() and b() == c() whenever consecutive calls to b return the same value and have the same aggregate side effects as a single call to b. For instance, there is no difference between the two expressions whenever b is a pure function with no side-effects.

The easiest way to show the slight difference:

>>> print(1) == print(2) == print(3)
1
2
3
True
>>> print(1) == print(2) and print(2) == print(3)
1
2
2
3
True

print() always returns None, so all we are doing is comparing Nones here, so the result is always True, but note that in the second case, print(2) is called twice, so we get two 2s in the output, while in the first case, the result is used for both comparisons, so it is only executed once.

Compare three (or more) variables in R with ifelse at once with loop

You need an & in there, so df_1$x == df_1$y & df_1$y == df_1$z, i.e. x equals y AND y equals x. You also don't need ifelse for this kind of comparison. Just do the comparison and add the output to your data frame:

df_1$match <- df_1$x == df_1$y & df_1$y == df_1$z

#### OUTPUT ####
x y z match
1 0 0 0 TRUE
2 1 2 2 FALSE
3 0 1 1 FALSE
4 2 2 2 TRUE
5 0 1 1 FALSE

However, if you really want "matched" an "not" you can do that too:

df_1$match <- ifelse(df_1$x == df_1$y & df_1$y == df_1$z, "matched", "not")

#### OUTPUT ####

x y z match
1 0 0 0 match
2 1 2 2 not
3 0 1 1 not
4 2 2 2 match
5 0 1 1 not

Edit based on comment:

For an arbitrary number of variables you could try something like this, which checks that unique only returns one value, i.e. all are equal:

df_1$match <- apply(df_1, 1, function(r) length(unique(r)) == 1)


Related Topics



Leave a reply



Submit