[c#] 모든 목록 항목에 동일한 값이 있는지 확인하고 반환하는 방법 또는 그렇지 않은 경우 “otherValue”를 반환하는 방법은 무엇입니까?

목록에있는 모든 항목의 값이 같으면 해당 값을 사용해야합니다. 그렇지 않으면 “otherValue”를 사용해야합니다. 이 작업을 수행하는 간단하고 명확한 방법을 생각할 수 없습니다.

컬렉션의 첫 번째 항목에 대한 특수 논리가있는 루프를 작성하는 깔끔한 방법을 참조하십시오 .



답변

var val = yyy.First().Value;
return yyy.All(x=>x.Value == val) ? val : otherValue; 

내가 생각할 수있는 가장 깨끗한 방법. val을 인라인하여 한 줄로 만들 수 있지만 First ()는 n 번 평가되어 실행 시간이 두 배가됩니다.

주석에 지정된 “빈 세트”동작을 통합하려면 위의 두 줄 앞에 한 줄을 더 추가하면됩니다.

if(yyy == null || !yyy.Any()) return otherValue;


답변

모두를위한 좋은 빠른 테스트 :

collection.Distinct().Count() == 1


답변

확실히 기존의 시퀀스 연산자에서 그러한 장치를 만들 수 있지만이 경우에는이 장치를 사용자 지정 시퀀스 연산자로 작성하는 경향이 있습니다. 다음과 같은 것 :

// 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>연습으로 남겨집니다. 🙂


답변

return collection.All(i => i == collection.First()))
    ? collection.First() : otherValue;.

또는 각 요소에 대해 First ()를 실행하는 것이 걱정되는 경우 (유효한 성능 문제가 될 수 있음) :

var first = collection.First();
return collection.All(i => i == first) ? first : otherValue;


답변

이것은 늦을 수 있지만 Eric의 대답에 따라 값 및 참조 유형에 대해 모두 작동하는 확장입니다.

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


답변

LINQ 사용에 대한 대안 :

var set = new HashSet<int>(values);
return (1 == set.Count) ? values.First() : otherValue;

나는 HashSet<T>다음과 비교하여 최대 ~ 6,000 개의 정수 목록에 대해 사용하는 것이 더 빠르다 는 것을 알았 습니다.

var value1 = items.First();
return values.All(v => v == value1) ? value1: otherValue;