What is an elegant way to check if 3 variables are equal when any of them can be a wildcard?

colinfang picture colinfang · Aug 10, 2011 · Viewed 7.3k times · Source

Say I have 3 char variables, a, b and c.
Each one can be '0', which is a special case and means it matches every char.

So if a is '0', I only need to check if b == c.
I want to check if a == b == c, but found the implementation in C# goes chaotic and lengthy.

Is there any creative or pretty solution you can offer?

update

for performance driven, take Erik A. Brandstadmoen's approach. for simplicity, use M4N's apprach, also i did some modification: !(query.Any() && query.Distinct().Skip(1).Any())

Answer

M4N picture M4N · Aug 10, 2011

Something like this:

var a = '1';
var b = '0';
var c = '1';

var chars = new List<char> { a, b, c };
var filtered = chars.Where(ch => ch != '0');
var allEqual = filtered.Count() == 0 || filtered.Distinct().Count() == 1;

To explain the solution:

  • first put all chars into a list
  • exclude all chars which are '0': .Where(ch => ch != '0')
  • all remaining chars are equal if either:
    • the remaining collection contains no elements: chars.Count() == 0
    • or the number of unique remaining elements is 1: chars.Distinct().Count() == 1

Update: here's a different version, which does not use LINQ but is still and readable (IMO). It is implemented as a method and can be called with any number of characters to be tested:

public bool AllEqualOrZero(params char[] chars)
{
    if (chars.Length <= 1) return true;
    char? firstNonZero = null;
    foreach (var c in chars)
    {
        if (c != '0')
        {
            firstNonZero = firstNonZero ?? c;
            if (c != firstNonZero) return false;
        }
    }
}

// Usage:
AllEqualOrZero('0', '0', '0'); // -> true
AllEqualOrZero('0', '1', '1'); // -> true
AllEqualOrZero('2', '1', '0'); // -> false
AllEqualOrZero();              // -> true
AllEqualOrZero('1');           // -> true