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.
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;
Good quick test for all equal:
collection.Distinct().Count() == 1
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. :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With