How to check if all list items have the same value and return it, or return an “otherValue” if they don’t?
If all the items in a list have the same value, then I need to use that value,开发者_如何学JAVA 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. :-)
return collection.All(i => i == collection.First()))
? collection.First() : otherValue;.
Or if you're worried about executing First() for each element (which could be a valid performance concern):
var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;
This may be late, but an extension that works for value and reference types alike based on Eric's answer:
public static partial class Extensions
{
public static Nullable<T> Unanimous<T>(this IEnumerable<Nullable<T>> sequence, Nullable<T> other, IEqualityComparer comparer = null) where T : struct, IComparable
{
object first = null;
foreach(var item in sequence)
{
if (first == null)
first = item;
else if (comparer != null && !comparer.Equals(first, item))
return other;
else if (!first.Equals(item))
return other;
}
return (Nullable<T>)first ?? other;
}
public static T Unanimous<T>(this IEnumerable<T> sequence, T other, IEqualityComparer comparer = null) where T : class, IComparable
{
object first = null;
foreach(var item in sequence)
{
if (first == null)
first = item;
else if (comparer != null && !comparer.Equals(first, item))
return other;
else if (!first.Equals(item))
return other;
}
return (T)first ?? other;
}
}
public int GetResult(List<int> list){
int first = list.First();
return list.All(x => x == first) ? first : SOME_OTHER_VALUE;
}
An alternative to using LINQ:
var set = new HashSet<int>(values);
return (1 == set.Count) ? values.First() : otherValue;
I have found using HashSet<T>
is quicker for lists of up to ~ 6,000 integers compared with:
var value1 = items.First();
return values.All(v => v == value1) ? value1: otherValue;
A slight variation on the above simplified approach.
var result = yyy.Distinct().Count() == yyy.Count();
If a array is of type multidimension like below then we have to write below linq to check the data.
example: here elements are 0 and i am checking all values are 0 or not.
ip1=
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
var value=ip1[0][0]; //got the first index value
var equalValue = ip1.Any(x=>x.Any(xy=>xy.Equals())); //check with all elements value
if(equalValue)//returns true or false
{
return "Same Numbers";
}else{
return "Different Numbers";
}
精彩评论