Reputation: 18650
Hi say I have three ints: value1, value2 and value3.
How do I best determine if they are all the same?
I tried:
return value1 == value2 == value3
But this said:
Operator '==' cannot be applied to operands of type 'bool' and 'int'.
So I guess it compares the first two which returns a boolean which it tries to compare to the third.
I could go:
return value1 == value2 && value2 == value3;
But this seems to be getting untidy.
Anybody have a good suggestion?
Upvotes: 13
Views: 17477
Reputation: 5265
The accepted answer works fine, but I needed to support different types too, so this is the generic version
public static bool AllSame<T>(params T[] items)
{
var first = true;
T comparand = default;
foreach (var i in items)
{
if (first) comparand = i;
else if (!i.Equals(comparand)) return false;
first = false;
}
return true;
}
usage:
if (AllSame(true, false, true)) // false
if (AllSame(5, 5, 5)) // true
if (AllSame(record1 , record2, record3))
Upvotes: -1
Reputation: 1
This is what I would do
if((value1 == value2) && (value1 == value3) && (value2 == value3))
{
//Whatever you want here
}
Upvotes: -1
Reputation: 187
You can do it like this also
bool AllSame(int a, int b, int c, int comparand) {
return board[a] == comparand && board[b] == comparand && board[c] == comparand;
}
Upvotes: 0
Reputation: 4440
Using LINQ it would be best to us Any()
. Why Any()
instead of All()
is because All()
will test the predicate on all the items of the collection while Any()
will exit as soon as and item match the predicate.
Here i use a reverse check. I am looking for any item that will be different than the item "a". So as soon it find one different we know they are not all equals so it exit and return true. So it will only test item "b", "c" and "d".
// all values to compare
var a = 4;
var b = 4;
var c = 4;
var d = 8;
var e = 6;
var f = 4;
// return if any of the following is different and negate to get a true
var areSame = (!new[] { b, c, d, e, f}.Any(i => i != a));
If you override equals you can create generic extensions from this that is reusable and can work for multiple type as long as they implement IEqualityComparer<T>
Upvotes: -1
Reputation: 7
int nOneInput = 5;
int nTwoInput = 5;
int nThreeInput = 5;
if ((nOneInput + nTwoInput + nThreeInput ) / 3 == nOneInput )
{
// all 3 sides are equal when...
// the sum of all 3 divided by 3 equals one of the values
}
Upvotes: -1
Reputation: 3371
I modified my original answer to include a method that is more general purpose and that does not rely on LINQ or extension methods. I think it's safe to assume this method would be more performant based on the fact that it doesn't have to enumerate the entire list to determine uniqueness when there are values that are different early on in the list.
class Program
{
static void Main(string[] args)
{
int value1 = 1, value2 = 2, value3 = 1;
Console.WriteLine(AllAreEqual<int>(value1, value2, value3));
Console.Write("V2: 1 value ");
Console.WriteLine(AllAreEqual_V2<int>(1));
Console.Write("V2: no value ");
Console.WriteLine(AllAreEqual_V2<int>());
Console.Write("V2: 3 values, same ");
Console.WriteLine(AllAreEqual_V2<int>(1, 1, 1));
Console.Write("V2: 3 values, different ");
Console.WriteLine(AllAreEqual_V2<int>(1, 1, 2));
Console.Write("V2: 2 values, same ");
Console.WriteLine(AllAreEqual_V2<int>(1, 1));
Console.Write("V2: 2 values, different ");
Console.WriteLine(AllAreEqual_V2<int>(1, 2));
Console.ReadKey();
}
static bool AllAreEqual<T>(params T[] args)
{
return args.Distinct().ToArray().Length == 1;
}
static bool AllAreEqual_V2<T>(params T[] args)
{
if (args.Length == 0 || args.Length == 1)
{
return true;
}
if (args.Length == 2)
{
return args[0].Equals(args[1]);
}
T first = args[0];
for (int index = 1; index < args.Length; index++)
{
if (!first.Equals(args[index]))
{
return false;
}
}
return true;
}
}
Upvotes: 6
Reputation: 24413
If you are just looking for elegance (Considering your already have a solution that has nothing wrong with it ) , you could go with good'ol LINQ. This can handle three or more.
class Program
{
static void Main(string[] args)
{
List<int> mylist = new List<int>();
mylist.Add(1);
mylist.Add(1);
mylist.Add(1);
mylist.Add(1);
bool allElementsAreEqual = mylist.All( x => ( x == mylist.First() ));
}
}
Upvotes: 0
Reputation: 11608
That seems fine to me. The only comment I have is that you should introduce an 'explaining variable' for the equation. Besides explaining the calculation, the return now provides a nice place for a breakpoint or a tracepoint when inspecting the result.
bool allThreeAreEqual = value1 == value2 && value2 == value3;
return allThreeAreEqual;
Upvotes: 6
Reputation: 283733
The second seems just fine to me.
As the list gets longer, that could get unwieldy. In which case I'd write an extension method along the lines of AllSame
.
bool AllSame(this IEnumerable<int> list)
{
bool first = true;
int comparand = 0;
foreach (int i in list) {
if (first) comparand = i;
else if (i != comparand) return false;
first = false;
}
return true;
}
or use the params
keyword:
bool AllSame(params int[] list)
{
return (list as IEnumerable<int>).AllSame();
}
Then you can just write:
if (AllSame(value1, value2, value3, value4, value5)) ...
Upvotes: 9