Подтвердить что ты не робот

Удалить элементы из списка 1 не в списке 2

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

var list = new List<int> {1, 2, 2, 4, 5};
var list2 = new List<int> { 4, 5 };

// Remove all list items not in List2
// new List Should contain {4,5}    
// The lambda expression is the Predicate.
list.RemoveAll(item => item. /*solution expression here*/ );

// Display results.
foreach (int i in list)
{
    Console.WriteLine(i);
}
4b9b3361

Ответ 1

Вы можете сделать это с помощью RemoveAll, используя Contains:

list.RemoveAll( item => !list2.Contains(item));

В качестве альтернативы, если вы просто хотите пересечение, использование Enumerable.Intersect будет более эффективным:

list = list.Intersect(list2).ToList();

Разница в том, что в последнем случае вы не будете получать повторяющиеся записи. Например, если list2 содержит 2, в первом случае вы получите {2,2,4,5}, во втором - {2,4,5}.

Ответ 2

Этот вопрос был отмечен как ответ, но есть улов. Если ваш список содержит объект, а не скаляр, вам нужно сделать немного больше работы.

Я пробовал это снова и снова с помощью Remove() и RemoveAt() и всех видов, и никто из них не работал правильно. Я не мог даже заставить Contains() работать правильно. Никогда ничего не соответствовало. Я был в тупике, пока не получил подозрение, что, возможно, он не смог правильно подобрать элемент.

Когда я это понял, я переделал класс item для реализации IEquatable, а затем начал работать.

Вот мое решение:

class GenericLookupE : IEquatable<GenericLookupE>
{
    public string   ID  { get; set; }

    public bool     Equals( GenericLookupE other )
    {
        if ( this.ID == other.ID )      return true;

        return false;
    }
}

После того, как я это сделал, вышеупомянутый ответ RemoveAll() Reed Copsey отлично работал у меня.

Смотрите: http://msdn.microsoft.com/en-us/library/bhkz42b3.aspx

Ответ 3

list = list.Except(list2).ToList();

Ответ 4

Упрощенное решение для объектов, нежели horace, дало:

Если ваш список содержит объект, а не скаляр, это просто, удалив с помощью одного выбранного свойства объектов:

    var a = allActivePatientContracts.RemoveAll(x => !allPatients.Select(y => y.Id).Contains(x.PatientId));