Используя linq или иначе, как проверить, имеют ли все элементы списка одинаковое значение и возвращают его, или возвращают "otherValue", если они не нужны?
Если все элементы в списке имеют одинаковое значение, мне нужно использовать это значение, иначе мне нужно использовать "otherValue". Я не могу придумать простой и понятный способ сделать это.
см. также Упрощенный способ записи цикла, который имеет специальную логику для первого элемента в коллекции.
Ответы
Ответ 1
var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue;
Самый чистый способ, о котором я могу думать. Вы можете сделать его одним лайнером, вставив val, но First() будет оцениваться n раз, удваивая время выполнения.
Чтобы включить поведение "пустого набора", указанное в комментариях, вы просто добавляете еще одну строку перед двумя:
if(yyy == null || !yyy.Any()) return otherValue;
Ответ 2
Хорошая быстрая проверка для всех равных:
collection.Distinct().Count() == 1
Ответ 3
Хотя вы, конечно, можете построить такое устройство из существующих операторов последовательности, я бы в этом случае был бы склонен записать это как пользовательский оператор последовательности. Что-то вроде:
// 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;
}
Это довольно ясно, коротко, охватывает все случаи и не требует излишнего создания дополнительных итераций последовательности.
Приведение этого в общий метод, который работает на IEnumerable<T>
, остается в виде упражнения.: -)
Ответ 4
return collection.All(i => i == collection.First()))
? collection.First() : otherValue;.
Или, если вы беспокоитесь о выполнении First() для каждого элемента (что может быть актуальной проблемой производительности):
var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;
Ответ 5
public int GetResult(List<int> list){
int first = list.First();
return list.All(x => x == first) ? first : SOME_OTHER_VALUE;
}
Ответ 6
Это может быть запоздалым, но расширение, которое работает для значений и ссылочных типов, на основе ответа Эрика:
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;
}
}
Ответ 7
Альтернатива использованию LINQ:
var set = new HashSet<int>(values);
return (1 == set.Count) ? values.First() : otherValue;
Я нашел, что использование HashSet<T>
быстрее для списков до ~ 6000 целых чисел по сравнению с:
var value1 = items.First();
return values.All(v => v == value1) ? value1: otherValue;
Ответ 8
Небольшое отклонение от упрощенного подхода.
var result = yyy.Distinct().Count() == yyy.Count();
Ответ 9
Если массив имеет многомерность типа, как показано ниже, мы должны написать ниже linq для проверки данных.
example: здесь элементы равны 0, и я проверяю, что все значения равны 0 или нет.
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";
}