해당 목록이 다른 목록의 하위 집합인지 확인하는 방법에 대한 아이디어가 있습니까?
구체적으로, 나는
List<double> t1 = new List<double> { 1, 3, 5 };
List<double> t2 = new List<double> { 1, 5 };
LINQ를 사용하여 t2가 t1의 하위 집합인지 확인하는 방법은 무엇입니까?
답변
bool isSubset = !t2.Except(t1).Any();
답변
세트로 작업하는 경우 List 대신 HashSet을 사용하십시오. 그런 다음 간단히 IsSubsetOf () 를 사용할 수 있습니다
HashSet<double> t1 = new HashSet<double>{1,3,5};
HashSet<double> t2 = new HashSet<double>{1,5};
bool isSubset = t2.IsSubsetOf(t1);
LINQ를 사용하지 않아서 죄송합니다. 🙁
목록을 사용해야하는 경우 @Jared의 솔루션은 존재하는 반복되는 요소를 제거해야한다는 경고와 함께 작동합니다.
답변
당신이 경우 단위 테스트 당신은 또한 활용할 수 CollectionAssert.IsSubsetOf의 방법 :
CollectionAssert.IsSubsetOf(subset, superset);
위의 경우 이는 다음을 의미합니다.
CollectionAssert.IsSubsetOf(t2, t1);
답변
이것은 여기에 게시 된 다른 솔루션, 특히 최고의 솔루션보다 훨씬 효율적인 솔루션입니다.
bool isSubset = t2.All(elem => t1.Contains(elem));
t2에서 t1에없는 단일 요소를 찾을 수 있으면 t2가 t1의 하위 집합이 아님을 알 수 있습니다. 이 방법의 장점은 .Except 또는 .Intersect를 사용하는 솔루션과 달리 추가 공간을 할당하지 않고 모든 위치에서 수행된다는 것입니다. 또한이 솔루션은 하위 집합 조건을 위반하는 단일 요소를 찾은 후 다른 요소는 계속 검색하면서 중단 될 수 있습니다. 아래는 최적의 긴 형태의 솔루션이며 위의 속기 솔루션보다 테스트에서 약간 빠릅니다.
bool isSubset = true;
foreach (var element in t2) {
if (!t1.Contains(element)) {
isSubset = false;
break;
}
}
모든 솔루션에 대한 기초적인 성능 분석을 수행했으며 그 결과는 극적입니다. 이 두 솔루션은 .Except () 및 .Intersect () 솔루션보다 약 100 배 빠르며 추가 메모리를 사용하지 않습니다.
답변
확장 방법으로 @Cameron의 솔루션 :
public static bool IsSubsetOf<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
return !a.Except(b).Any();
}
용법:
bool isSubset = t2.IsSubsetOf(t1);
(이것은 비슷하지만 @Michael의 블로그에 게시 된 것과 동일하지는 않습니다)
답변
@Cameron 및 @Neil의 답변을 바탕으로 Enumerable 클래스와 동일한 용어를 사용하는 확장 메서드를 작성했습니다.
/// <summary>
/// Determines whether a sequence contains the specified elements by using the default equality comparer.
/// </summary>
/// <typeparam name="TSource">The type of the elements of source.</typeparam>
/// <param name="source">A sequence in which to locate the values.</param>
/// <param name="values">The values to locate in the sequence.</param>
/// <returns>true if the source sequence contains elements that have the specified values; otherwise, false.</returns>
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> values)
{
return !values.Except(source).Any();
}
답변
여기서 우리
t2
는 부모 목록 (iet1
)에 포함되지 않은 자식 목록 (ie ) 에 요소가 존재하는지 확인합니다 .
예 :
bool isSubset = !(t2.Any(x => !t1.Contains(x)));