code

두 목록의 차이점

codestyles 2020. 8. 14. 07:44
반응형

두 목록의 차이점


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

강조하는 것이 중요하다고 생각합니다. 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);

(you can also call ToList() after Except(), if you don't like referencing lazy collections.)

The Except() method compares the values using the default comparer, if the values being compared are of base data types, such as int, string, decimal etc.

Otherwise the comparison will be made by object address, which is probably not what you want... In that case, make your custom objects implement IComparable (or implement a custom IEqualityComparer and pass it to the Except() method).


Since the Except extension method operates on two IEumerables, it seems to me that it will be a O(n^2) operation. If performance is an issue (if say your lists are large), I'd suggest creating a HashSet from list1 and use HashSet's ExceptWith method.


bit late but here is working solution for me

 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

In above mention code I am getting the properties difference between my base class and derived class list


(LINQ) (C#) This example shows how to use LINQ to compare two lists of strings and output those lines that are in names1.txt but not in names2.txt with .Except().

    // Create the IEnumerable data sources.  
    string[] names1 = System.IO.File.ReadAllLines(@"../../../names1.txt");  
    string[] names2 = System.IO.File.ReadAllLines(@"../../../names2.txt");  

    // Create the query. Note that method syntax must be used here.  
    IEnumerable<string> differenceQuery = names1.Except(names2);  

    // Execute the query.  
    Console.WriteLine("The following lines are in names1.txt but not names2.txt");  
    foreach (string s in differenceQuery)  
        Console.WriteLine(s);  

    // Keep the console window open in debug mode.  
    Console.WriteLine("Press any key to exit");  
    Console.ReadKey(); 

var list3 = list1.Where(x => !list2.Any(z => z.Id == x.Id)).toList();

Note: list3 will contain the items or objects that are not in both lists.


var resultList = checklist.Where(p => myList.All(l => p.value != l.value)).ToList();

If both your lists implement IEnumerable interface you can achieve this using LINQ.

list3 = list1.where(i => !list2.contains(i));

        List<int> list1 = new List<int>();
        List<int> list2 = new List<int>();
        List<int> listDifference = new List<int>();

        foreach (var item1 in list1)
        {
            foreach (var item2 in list2)
            {
                if (item1 != item2)
                    listDifference.Add(item1);
            }
        }

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

참고URL : https://stackoverflow.com/questions/5636438/difference-between-two-lists

반응형