CustomsObjects로 채워진 두 개의 일반 목록이 있습니다.
세 번째 목록에서 두 목록 (두 번째 목록의 항목없이 첫 번째 목록에있는 항목)의 차이점을 검색해야합니다.
사용 .Except()하는 것이 좋은 생각이라고 생각했지만 사용 방법을 모르겠습니다 .. 도움말!
CustomsObjects로 채워진 두 개의 일반 목록이 있습니다.
세 번째 목록에서 두 목록 (두 번째 목록의 항목없이 첫 번째 목록에있는 항목)의 차이점을 검색해야합니다.
사용 .Except()하는 것이 좋은 생각이라고 생각했지만 사용 방법을 모르겠습니다 .. 도움말!
답변:
사용하는 Except것이 바로 올바른 방법입니다. 만약 당신의 유형 대체 Equals하고 GetHashCode, 또는 당신은 단지 참조 유형 평등에 관심이있는 (즉, 두 개의 참조이다 그들이 동일한 객체를 참조하는 경우에만 "동일"), 당신은 그냥 사용할 수 있습니다 :
var list3 = list1.Except(list2).ToList();
예를 들어 ID로 동일성에 대한 사용자 정의 아이디어를 표현해야하는 경우 IEqualityComparer<T>. 예를 들면 :
public class IdComparer : IEqualityComparer<CustomObject>
{
public int GetHashCode(CustomObject co)
{
if (co == null)
{
return 0;
}
return co.Id.GetHashCode();
}
public bool Equals(CustomObject x1, CustomObject x2)
{
if (object.ReferenceEquals(x1, x2))
{
return true;
}
if (object.ReferenceEquals(x1, null) ||
object.ReferenceEquals(x2, null))
{
return false;
}
return x1.Id == x2.Id;
}
}
그런 다음 다음을 사용하십시오.
var list3 = list1.Except(list2, new IdComparer()).ToList();
이렇게하면 모든 중복 요소가 제거됩니다. 중복을 보존해야하는 경우 list2다음과 같이 집합을 만들고 사용하는 것이 가장 쉬울 것입니다 .
var list3 = list1.Where(x => !set2.Contains(x)).ToList();
다음과 같이 할 수 있습니다.
var result = customlist.Where(p => !otherlist.Any(l => p.someproperty == l.someproperty));
Any을해야 All당신이 그런 식으로 작업을 수행하려는 경우. 두 번째 목록에 첫 번째 목록의 항목이있을 수 있지만 첫 번째 목록이 확인되지 않은 경우 즉시 p.someproperty != l.someproperty. 이로 인해 두 목록에 모두있는 항목이 반환됩니다. 이것을 찬성 한 6 명에게 수치심.
강조하는 것이 중요하다고 생각합니다. Except 메서드 를 사용 하면 두 번째 항목 만 제외하고 첫 번째 항목에있는 항목 만 반환됩니다. 첫 번째에 나타나지 않는 두 번째 요소는 반환하지 않습니다.
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2).ToList(); //list3 contains only 1, 2
그러나 두 목록의 실제 차이를 원한다면 :
두 번째 항목이없는 첫 번째 항목과 첫 번째 항목이없는 두 번째 항목입니다.
Except를 두 번 사용해야합니다.
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list3 = list1.Except(list2); //list3 contains only 1, 2
var list4 = list2.Except(list1); //list4 contains only 6, 7
var resultList = list3.Concat(list4).ToList(); //resultList contains 1, 2, 6, 7
또는 HashSet의 SymmetricExceptWith 메소드를 사용할 수 있습니다 . 그러나 다음과 같은 세트를 변경합니다.
var list1 = new List<int> { 1, 2, 3, 4, 5};
var list2 = new List<int> { 3, 4, 5, 6, 7 };
var list1Set = list1.ToHashSet(); //.net framework 4.7.2 and .net core 2.0 and above otherwise new HashSet(list1)
list1Set.SymmetricExceptWith(list2);
var resultList = list1Set.ToList(); //resultList contains 1, 2, 6, 7
var third = first.Except(second);
(당신은 또한 호출 할 수 있습니다 ToList()후 Except()당신이 게으른 컬렉션을 참조하는 마음에 들지 않으면.)
Except()값이 같은베이스 데이터 유형이다 비교되는 경우에있어서, 기본 비교를 사용하여 값을 비교 int, string, decimal등
그렇지 않으면 객체 주소로 비교가 이루어집니다. 이는 아마도 원하는 것이 아닐 것입니다 ...이 경우 사용자 지정 개체를 구현 IComparable(또는 사용자 지정을 구현 IEqualityComparer하고 Except()메서드에 전달 )합니다.
Except 확장 메서드는 두 개의 IEumerable에서 작동하기 때문에 O (n ^ 2) 작업이 될 것 같습니다. 성능이 문제인 경우 (목록이 큰 경우) list1에서 HashSet을 만들고 HashSet의 ExceptWith 메서드를 사용하는 것이 좋습니다.
Enumerable.Except내부적으로 사용 HashSet하거나 유사한 것. 순진한 O (n ^ 2) 알고리즘을 사용하지 않습니다.
내 해결책은 다음과 같습니다.
List<String> list1 = new List<String>();
List<String> list2 = new List<String>();
List<String> exceptValue = new List<String>();
foreach(String L1 in List1)
{
if(!List2.Contains(L1)
{
exceptValue.Add(L1);
}
}
foreach(String L2 in List2)
{
if(!List1.Contains(L2)
{
exceptValue.Add(L2);
}
}
조금 늦었지만 여기에 나를 위해 일하는 해결책이 있습니다.
var myBaseProperty = (typeof(BaseClass)).GetProperties();//get base code properties
var allProperty = entity.GetProperties()[0].DeclaringType.GetProperties();//get derived class property plus base code as it is derived from it
var declaredClassProperties = allProperty.Where(x => !myBaseProperty.Any(l => l.Name == x.Name)).ToList();//get the difference
위의 언급 코드에서 기본 클래스와 파생 클래스 목록 간의 속성 차이를 얻고 있습니다.
List<ObjectC> _list_DF_BW_ANB = new List<ObjectC>();
List<ObjectA> _listA = new List<ObjectA>();
List<ObjectB> _listB = new List<ObjectB>();
foreach (var itemB in _listB )
{
var flat = 0;
foreach(var itemA in _listA )
{
if(itemA.ProductId==itemB.ProductId)
{
flat = 1;
break;
}
}
if (flat == 0)
{
_list_DF_BW_ANB.Add(itemB);
}
}
두 목록 모두 IEnumerable 인터페이스를 구현하는 경우 LINQ를 사용하여이를 수행 할 수 있습니다.
list3 = list1.where(i => !list2.contains(i));
IEnumerable.Except대신 사용하십시오 .
Except입니다. 그러면 결과 목록은 고유 한 값을 가질 것입니다. 예 : returns{'A','A','B','C'}.Except({'B','C'}){'A'}