Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if all list items have the same value and return it, or return an “otherValue” if they don’t?

Tags:

c#

linq

If all the items in a list have the same value, then I need to use that value, otherwise I need to use an “otherValue”. I can’t think of a simple and clear way of doing this. When the list is empty it should return the "other" value.

See also Neat way to write loop that has special logic for the first item in a collection.

like image 264
Ian Ringrose Avatar asked Dec 08 '10 17:12

Ian Ringrose


3 Answers

var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue; 

Cleanest way I can think of. You can make it a one-liner by inlining val, but First() would be evaluated n times, doubling execution time.

To incorporate the "empty set" behavior specified in the comments, you simply add one more line before the two above:

if(yyy == null || !yyy.Any()) return otherValue;
like image 108
KeithS Avatar answered Nov 05 '22 08:11

KeithS


Good quick test for all equal:

collection.Distinct().Count() == 1
like image 37
Jeremy Bell Avatar answered Nov 05 '22 07:11

Jeremy Bell


Though you certainly can build such a device out of existing sequence operators, I would in this case be inclined to write this one up as a custom sequence operator. Something like:

// Returns "other" if the list is empty.
// Returns "other" if the list is non-empty and there are two different elements.
// Returns the element of the list if it is non-empty and all elements are the same.
public static int Unanimous(this IEnumerable<int> sequence, int other)
{
    int? first = null;
    foreach(var item in sequence)
    {
        if (first == null)
            first = item;
        else if (first.Value != item)
            return other;
    }
    return first ?? other;
}

That's pretty clear, short, covers all the cases, and does not unnecessarily create extra iterations of the sequence.

Making this into a generic method that works on IEnumerable<T> is left as an exercise. :-)

like image 23
Eric Lippert Avatar answered Nov 05 '22 09:11

Eric Lippert