Разница между двумя списками

У меня есть два общих списка, заполненных таможнями.

Мне нужно получить разницу между этими двумя списками (элементы, которые находятся в первом без элементов во втором) в третьем.

Я думал, что использование .Except() было хорошей идеей, но я не понимаю, как это использовать. Помогите!

Ответ 1

Использование Except - верный путь. Если ваш тип переопределяет Equals и GetHashCode, или вас интересует только равенство ссылочного типа (т.е. Две ссылки "равны", только если они ссылаются на один и тот же объект), вы можете просто использовать:

var list3 = list1.Except(list2).ToList();

Если вам нужно выразить собственное представление о равенстве, например, по идентификатору, вам нужно реализовать 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();

Ответ 2

Вы можете сделать что-то вроде этого:

var result = customlist.Where(p => !otherlist.Any(l => p.someproperty == l.someproperty));

Ответ 3

Я думаю, что важно подчеркнуть - использование Кроме метода вернет вам элементы, которые находятся в первом, без элементов только во втором. Он не возвращает те элементы в секунду, которые не появляются в первом.

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

Но если вы хотите получить реальную разницу между двумя списками:

Предметы, которые находятся в первом без предметов во втором и предметы, которые находятся во втором, без предметов в первом.

Вам нужно использовать исключение дважды:

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

Или вы можете использовать метод SymmetricExceptWith HashSet. Но это меняет набор, на котором вызывается:

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

Ответ 4

var third = first.Except(second);

(вы также можете вызвать ToList() после Except(), если вам не нравятся ссылки на ленивые коллекции.)

Метод Except() сравнивает значения с использованием сравнения по умолчанию, если сравниваемые значения относятся к базовым типам данных, таким как int, string, decimal и т.д.

В противном случае сравнение будет производиться по адресу объекта, что, вероятно, не то, что вы хотите... В этом случае создайте свои пользовательские объекты IComparable (или внесите пользовательский IEqualityComparer и передайте его в Except()).

Ответ 5

Поскольку метод расширения Except работает на двух IEumerables, мне кажется, что это будет операция O (n ^ 2). Если производительность является проблемой (если говорят, что ваши списки большие), я бы предложил создать HashSet из списка1 и использовать метод HashSet ExceptWith.

Ответ 6

бит поздно, но вот работающее решение для меня

 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

В приведенном выше кодексе я получаю разницу в свойствах между моим базовым классом и списком производных классов

Ответ 7

(LINQ) (С#) В этом примере показано, как использовать LINQ для сравнения двух списков строк и вывода тех строк, которые находятся в names1.txt, но не в names2.txt, с помощью .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(); 

Ответ 8

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

Примечание. list3 будет содержать элементы или объекты, которых нет в обоих списках. Примечание: это ToList() не toList()

Ответ 9

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

Ответ 10

Если оба списка реализуют интерфейс IEnumerable, вы можете достичь этого с помощью LINQ.

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

Ответ 11

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

Ответ 12

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