Используя 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";   
    }