How to determine if three ints are all equal - c#

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?

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)) ...

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;

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;
}
}

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() ));
}
}

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;
}

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
}

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>

This is what I would do
if((value1 == value2) && (value1 == value3) && (value2 == value3))
{
//Whatever you want here
}

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))

Related

Check if characters in String are in alphabetical order

I'm supposed to take in a string and return true if it is in alphabetical order. So far in my solution I am able to get true from "abc" but words like "aPple" throw a false. I am assuming this is because some of the characters are capitalized but I don't know where I am going wrong. This is what I have.
public bool IsAlphabetical(string s)
{
char[] c = s.ToCharArray();
Array.Sort(c);
return (c.SequenceEqual(s));
}
if you need not case-sensitive comparison, you can try this
public static bool IsAlphabetical(string s,bool checkWithoutCase=true)
{
var c = s.ToCharArray();
Array.Sort(c);
var equal = c.SequenceEqual(s);
// check without case
if (!equal && checkWithoutCase)
{
s = s.ToLower();
Array.Sort(c = s.ToCharArray());
equal = c.SequenceEqual(s);
}
return equal;
}
or linq variant ( I am not sure what is faster)
public static bool IsAlphabetical(string s, bool checkWithoutCase=true, bool checkWithCase=true)
{
var equal=false;
if (checkWithCase) equal= s.OrderBy(x => x).SequenceEqual(s);
// check without case
if (!equal && checkWithoutCase)
{
s=s.ToLower();
equal = s.OrderBy(x => x).SequenceEqual(s);
}
return equal;
}
I think that LINQ and array sorting is too much. A quick performance check proves that
https://dotnetfiddle.net/eoKP7Z
public static bool IsAlphabetical(string s, bool checkWithoutCase = true)
{
var comparisonType = checkWithoutCase ?
System.StringComparison.OrdinalIgnoreCase :
System.StringComparison.Ordinal;
for (var idx = 1; idx < s.Length; idx++)
{
if (string.Compare(s, idx - 1, s, idx, 1, comparisonType) > 0)
{
return false;
}
}
return true;
}

What's a good algorithm for checking if a given list of values alternates up and down?

Assuming the function takes in a list of double and an index to perform the check from, I need to check if the values alternates up and down consecutively.
For example, a list of [14.0,12.3,13.0,11.4] alternates consecutively but a list of [14.0,12.3,11.4,13.0] doesn't.
The algorithm doesn't have to be fast, but I'd like it to be compact to write (LINQ is totally fine). This is my current method, and it looks way too crude to my taste:
enum AlternatingDirection { Rise, Fall, None };
public bool CheckConsecutiveAlternation(List<double> dataList, int currDataIndex)
{
/*
* Result True : Fail
* Result False : Pass
*/
if (!_continuousRiseFallCheckBool)
return false;
if (dataList.Count < _continuousRiseFallValue)
return false;
if (currDataIndex + 1 < _continuousRiseFallValue)
return false;
AlternatingDirection direction = AlternatingDirection.None;
int startIndex = currDataIndex - _continuousRiseFallValue + 1;
double prevVal = 0;
for (int i = startIndex; i <= currDataIndex; i++)
{
if (i == startIndex)
{
prevVal = dataList[i];
continue;
}
if (prevVal > dataList[i])
{
prevVal = dataList[i];
switch (direction)
{
case AlternatingDirection.None:
direction = AlternatingDirection.Fall;
continue;
case AlternatingDirection.Rise:
direction = AlternatingDirection.Fall;
continue;
default:
//Two falls in a row. Not a signal.
return false;
}
}
if (prevVal < dataList[i])
{
prevVal = dataList[i];
switch (direction)
{
case AlternatingDirection.None:
direction = AlternatingDirection.Rise;
continue;
case AlternatingDirection.Fall:
direction = AlternatingDirection.Rise;
continue;
default:
//Two rise in a row. Not a signal.
return false;
}
}
return false;
}
//Alternated n times until here. Data is out of control.
return true;
}
Try this:
public static bool IsAlternating(double[] data)
{
var d = GetDerivative(data);
var signs = d.Select(val => Math.Sign(val));
bool isAlternating =
signs.Zip(signs.Skip(1), (a, b) => a != b).All(isAlt => isAlt);
return isAlternating;
}
private static IEnumerable<double> GetDerivative(double[] data)
{
var d = data.Zip(data.Skip(1), (a, b) => b - a);
return d;
}
Live demo
The idea is:
If the given list of values is alternating up and down, mathematically it means that it's derivative keeps changing its sign.
So this is exactly what this piece of code does:
Get the derivative.
Checks for sign fluctuations.
And the bonus is that it will not evaluate all of the derivative / signs arrays unless it is necessary.
I'd do it with a couple of consecutive zips, bundled in an extension method:
public static class AlternatingExtensions {
public static bool IsAlternating<T>(this IList<T> list) where T : IComparable<T>
{
var diffSigns = list.Zip(list.Skip(1), (a,b) => b.CompareTo(a));
var signChanges = diffSigns.Zip(diffSigns.Skip(1), (a,b) => a * b < 0);
return signChanges.All(s => s);
}
}
Edit: for completeness, here's how you'd use the feature:
var alternatingList = new List<double> { 14.0, 12.3, 13.0, 11.4 };
var nonAlternatingList = new List<double> { 14.0, 12.3, 11.4, 13.0 };
alternatingList.IsAlternating(); // true
nonAlternatingList.IsAlternating(); // false
I also changed the implementation to work on more types, making use of generics as much as possible.
Here is a small pseudo code. Assuming no repeated elements (can be handled easily though by few tweaks)
Idea is to have a sign variable which is alternating 1,-1,... that is multipled by the difference of two consecutive pairs, the difference multipled by this sign variable must always be positive. If it's not at some point, return false.
isUpAndDown(l):
if size(l) < 2: // empty,singleton list is always good.
return true
int sign = (l[0] < l[1] ? 1 : -1)
for i from 0 to n-1 (exclusive):
if sign * (l[i+1] - l[i]) < 0:
return false //not alternating
sign = sign * -1
end for
return true //all good
You may create kind of a signed array first:
double previous = 0;
var sign = myList.Select(x => {
int s = Math.Sign(x - previous);
previos = x;
return s;
});
This gives you a list similar to
{ -1, 1, -1, ... }
Now you can take a similar appraoch as the previos Select-statement to check if a -1 follows a 1:
var result = sign.All(x => {
bool b = x == -previous;
previous = x;
return b;
});
Now result is true if your list alternates, false otherwise.
EDIT: To ensure that the very first check within the second query also passes add previous = -sign[0]; before the second query.
Assuming that two equal values in a row are not acceptable (if they are, just skip over equal values):
if (dataList[0] == dataList[1])
return false;
bool nextMustRise = dataList[0] > dataList[1];
for (int i = 2; i < dataList.Count; i++) {
if (dataList[i - 1] == dataList[i] || (dataList[i - 1] < dataList[i]) != nextMustRise)
return false;
nextMustRise = !nextMustRise;
}
return true;
public double RatioOfAlternations(double[] dataList)
{
double Alternating = 0;
double Total = (dataList.Count()-2);
for (int (i) = 0; (i) < Total; (i)++)
{
if (((dataList[i+1]-dataList[i])*(dataList[i+2]-dataList[i+1]))<0)
// If previous change is opposite sign to current change, this will be negative
{
Alternating++;
}
else
{
}
}
return (Alternating/Total);
}

Is there a way to optimize a foreach with LINQ?

How can I check an array of integers contain an integer value.
How can i do it in LiNQ. I have to do it in LINQ Query..
Like:-
Int test = 10;
var a = from test in Test
where test.Contains(1,2,3,4,5,6,7,8,9,10)
select test.id
Currently I'm doing it through Extensions Method but the method is slow.
public static bool ContainsAnyInt(this int int_, bool checkForNotContain_, params int[] values_)
{
try
{
if (values_.Length > 0)
{
foreach (int value in values_)
{
if (value == int_)
{
if (checkForNotContain_)
return false;
else
return true;
}
}
}
}
catch (Exception ex)
{
ApplicationLog.Log("Exception: ExtensionsMerhod - ContainsAnyInt() Method ---> " + ex);
}
}
I have to do it in an optimize way because data is huge...
In most cases Linq is slower than a foreach.
You can just call the Linq Extension method:
int[] values = new[]{3,3};
bool hasValue = values.Contains(3);
It accomplishes the same thing as your extension method.
Would the following not work faster (untested):
public static bool ContainsAnyInt(this int int_, bool checkForNotContain_, params int[] values_)
{
if(values_ != null && values_.Contains(int_))
{
return !checkForNotContain_;
}
else
return false;
}
Working within your constraints, I would sort the arrays of values in each of the test classes so you could do something like:
int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var results = from test in tests
where test.BinaryContains(values)
select test.id;
And the test class would look something like:
class Test
{
public int id;
public int[] vals; //A SORTED list of integers
public bool BinaryContains(int[] values)
{
for (int i = 0; i < values.Length; i++)
if (values[i] >= vals[0] && values[i] <= vals[vals.Length])
{
//Binary search vals for values[i]
//if match found return true
}
return false;
}
}
Of course there are tons of ways you could optimize this further. If memory is not a concern, a Dictionary could give you all of the Test classes that contain a given integer.

Easy way to compare values of more than 3 variables?

I want to check whether these variables have same values.
EXAMPLE:
int a = 5;
int b = 5;
int c = 5;
int d = 5;
int e = 5;
. . .
int k = 5;
if(a==b && b==c && c==d && d==e && .... && j==k)
{
//this is Complex way and not well understandable.
}
Any easy way to Compare all are same?
LIKE in below example
if(a==b==c==d==e.....j==k)
{
//Understandable but not work
}
how about something like this:
if (Array.TrueForAll<int>(new int[] {a, b, c, d, e, f, g, h, i, j, k },
val => (a == val))) {
// do something
}
With this many variables, would it make sense to move them into an array?
You could then test to see if they are all equal using Linq expressions like myarray.Distinct().Count() == 1; or perhaps myarray.All(r => r == 5);
You could create a var args method to do that:
bool intsEqual (params int[] ints) {
for (int i = 0; i < ints.Length - 1; i++) {
if (ints[i] != ints[i+1]) {
return False;
}
}
return True;
}
Then just call it with all your ints as parameters:
if (intsEqual(a, b, c, d, e, f, g, h, i, j, k)) {
doSomeStuff();
}
Just a thought, but if you can calculate the standard deviation of the entire list, and it is equal to zero, you would have your answer.
Here's an answer on the site that addresses this that may help with that: Standard deviation of generic list?
Interesting problem. Good luck with it.
I agree that the easiest way is to place them all into a list and then use the following to compare. This is in essence looping through and comparing to the first value, but this is a little cleaner.
var match = counts.All(x => x == counts[0])
How about
int common = a;
if (a==common && b==common && c==common && d==common && .... && k==common)
You could write a helper method like this:
public static bool AllEqual<T> (params T[] values) where T : IEquatable<T>
{
if (values.Length < 2) return true;
for (int i = 1; i < values.Length; i++)
if (!values[i].Equals (values[0])) return false;
return true;
}
This will be subtly different to the == operator in special cases, though:
AllEqual (double.NaN, double.NaN).Dump(); // True
(double.NaN == double.NaN).Dump(); // False
It doesn't work because a==b evaluates to a boolean which can't be compared to an integer, c. What you have seems to be the best way.
You might consider putting the values in an array and using a for() loop. It isn't really any simpler, but it might help if the number of values changed.
You could use a variable argument helper function to perform the comparison pretty easily.
static bool CompareLongList(params int[] args)
{
if (args.Length > 1)
{
int value = args[0];
for (int i = 1; i < args.Length; ++i)
{
if (value != args[i])
return false;
}
}
return true;
}
Then you would just use the function as follows
if(CompareLongList(a,b,c,d,e,f,j,h,i,j,k))
{
// True Code
}
I know it's an old question I came across but I was wondering what's wrong with:
if (a == (b & c & d & e & f & g & h & i & j & k))
{
}
Compare the same elements in array:
same = len(uniq([1,2,3,4])) == 1
Use Linq Query.
var greatestInt = new List() { a,b,c,d,e,f}.Max();
Bitwise and is a possible way to check multiple variables for same value.
Such a helper method could of course also check for equality instead of using the '&' operator. Helper method accepting a params array of variables seems to be the right method here. We could adjust this method to accept a generic argument also, but there are only a few data types which support boolean logical operators anyways in C# (and other languages).
Testing with a high value of Int32 to check validity of this:
void Main()
{
int a = 1234567891;
int b = 1234567891;
int c = 1234567891;
int d = 1234567891;
int e = 1234567891;
int f = 1234567891;
int g = 1234567891;
int h = 1234567891;
int i = 1234567891;
int j = 1234567891;
int k = 1234567891;
bool areAllSameValue = IntUtils.AreAllVariablesSameValue(a,b,c,d,e,f,g,h,i,j,k);
areAllSameValue.Dump(); //Linqpad method - dump this code into Linqpad to test
}
public class IntUtils
{
public static bool AreAllVariablesSameValue(params int[] values)
{
if (values == null || !values.Any())
{
return false;
}
int bitWiseAndValue = values[0];
foreach (var value in values)
{
bitWiseAndValue &= value;
}
return bitWiseAndValue == values[0];
}
}
This spots also if one of the values got a different sign (negative number).

C#: how do you check lists are the same size & same elements?

There are two lists of string
List<string> A;
List<string> B;
What is the shortest code you would suggest to check that A.Count == B.Count and each element of A in B and vise versa: every B is in A (A items and B items may have different order).
If you don't need to worry about duplicates:
bool equal = new HashSet<string>(A).SetEquals(B);
If you are concerned about duplicates, that becomes slightly more awkward. This will work, but it's relatively slow:
bool equal = A.OrderBy(x => x).SequenceEquals(B.OrderBy(x => x));
Of course you can make both options more efficient by checking the count first, which is a simple expression. For example:
bool equal = (A.Count == B.Count) && new HashSet<string>(A).SetEquals(B);
... but you asked for the shortest code :)
A.Count == B.Count && new HashSet<string>(A).SetEquals(B);
If different frequencies of duplicates are an issue, check out this question.
If you call Enumerable.Except() on the two lists, that will return an IEnumerable<string> containing all of the elements that are in one list but not the other. If the count of this is 0, then you know that the two lists are the same.
var result = A.Count == B.Count && A.Where(y => B.Contains(y)).Count() == A.Count;
Maybe?
How about a simple loop?
private bool IsEqualLists(List<string> A, List<string> B)
{
for(int i = 0; i < A.Count; i++)
{
if(i < B.Count - 1) {
return false; }
else
{
if(!String.Equals(A[i], B[i]) {
return false;
}
}
}
return true;
}
If you aren't concerned about duplicates, or you're concerned about duplicates but not overly concerned about performance micro-optimisations, then the various techniques in Jon's answer are definitely the way to go.
If you're concerned about duplicates and performance then something like this extension method should do the trick, although it really doesn't meet your "shortest code" criteria!
bool hasSameElements = A.HasSameElements(B);
// ...
public static bool HasSameElements<T>(this IList<T> a, IList<T> b)
{
if (a == b) return true;
if ((a == null) || (b == null)) return false;
if (a.Count != b.Count) return false;
var dict = new Dictionary<string, int>(a.Count);
foreach (string s in a)
{
int count;
dict.TryGetValue(s, out count);
dict[s] = count + 1;
}
foreach (string s in b)
{
int count;
dict.TryGetValue(s, out count);
if (count < 1) return false;
dict[s] = count - 1;
}
return dict.All(kvp => kvp.Value == 0);
}
(Note that this method will return true if both sequences are null. If that's not the desired behaviour then it's easy enough to add in the extra null checks.)

Categories

Resources