Как проверить, все ли элементы списка имеют одинаковое значение и вернуть его, или вернуть «otherValue», если они этого не делают? - PullRequest
109 голосов
/ 08 декабря 2010

Если все элементы в списке имеют одинаковое значение, тогда мне нужно использовать это значение, в противном случае мне нужно использовать «otherValue». Я не могу придумать простой и понятный способ сделать это.

См. Также Удобный способ написания цикла, который имеет специальную логику для первого элемента в коллекции.

Ответы [ 9 ]

139 голосов
/ 08 декабря 2010
var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue; 

Самый чистый способ, который я могу придумать.Вы можете сделать его однострочным, вставив val, но First () будет оцениваться n раз, удваивая время выполнения.

Чтобы включить поведение «пустой набор», указанное в комментариях, вы просто добавляете ещестрока перед двумя выше:

if(yyy == null || !yyy.Any()) return otherValue;
86 голосов
/ 31 марта 2011

Хороший быстрый тест для всех равных:

collection.Distinct().Count() == 1
20 голосов
/ 08 декабря 2010

Хотя вы, конечно, можете создать такое устройство из существующих операторов последовательности, я бы в этом случае был склонен записать это как пользовательский оператор последовательности.Примерно так:

// 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;
}

Это довольно понятно, коротко, охватывает все случаи и не создает ненужных дополнительных итераций последовательности.1006 * оставлено в качестве упражнения.: -)

12 голосов
/ 08 декабря 2010
return collection.All(i => i == collection.First())) 
    ? collection.First() : otherValue;.

Или, если вы беспокоитесь о выполнении First () для каждого элемента (что может быть допустимой проблемой производительности):

var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;
3 голосов
/ 24 ноября 2014

Это может быть поздно, но расширение, которое работает как для значений, так и для ссылочных типов, основано на ответе Эрика:

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;
    }
}
1 голос
/ 06 февраля 2017

Небольшое отклонение от вышеуказанного упрощенного подхода.

var result = yyy.Distinct().Count() == yyy.Count();

1 голос
/ 03 февраля 2015

Альтернатива использованию 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;
1 голос
/ 08 декабря 2010
public int GetResult(List<int> list){
int first = list.First();
return list.All(x => x == first) ? first : SOME_OTHER_VALUE;
}
0 голосов
/ 07 апреля 2017

Если массив имеет многомерный тип, как показано ниже, мы должны написать ниже linq для проверки данных.

пример: здесь элементы равны 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";   
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...