2015-04-11 2 views
0

У меня есть модель:удаления элементов из списка, которые существуют в другом списке на основе элемента ID

public class Post 
{ 
    public int PostId { get; set; } 
    public string Description { get; set; } 
} 

У меня есть два списка:

List<Post> posts 
List<Post> exceptions 

Я хочу, чтобы удалить все элементы в «сообщениях "что имеет совпадающие сообщения дан из пункта в„исключении“

Я пробовал:

foreach (var post in posts) 
{ 
    if (exceptions.Where(x => x.PostId == post.PostId) != null) 
    { 
     posts.RemoveAll(x => x.PostId == post.PostId); 
    } 
} 

, но я уверен, что есть более чистый способ сделать это.

Спасибо!

+0

'exceptions.Where (х => x.PostId == post.PostId) = null' - это всегда будет оценивать значение 'true', поскольку [' Where'] (https://msdn.microsoft.com/en-us/library/vstudio/bb534803%28v=vs.100%29.aspx) никогда не вернется 'null' (возможно, пустая перечисление). –

ответ

1

Просто получить posts вы хотите сохранить и переопределить исходный список:

posts = posts.Where(p => !exceptions.Any(e => e.PostId == p.PostId).ToList(); 
0

Первый пункт: вы не можете удалить элемент сообщений, когда вы делаете foreach на сообщениях.

Вместо этого вы должны использовать цикл for.

Второй пункт: используйте карту между каждым постом и сообщением объекта, содержащим идентификатор thid, перед циклом. Таким образом, у вас не должно быть сложности n^2.

0

Для упрощения вычисления примера я реализовал два списка, чтобы содержать целые числа, а не объекты класса, но логика одинакова. Насколько я понял из вашего примера, вы хотите удалить все объекты сообщений, доступные в списке исключений.

List<int> posts = new List<int>() { -3, -2, -1, 0, 1, 2, 3 }; 
    List<int> exceptions = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

    IEnumerable<int> intersection = exceptions.Intersect(posts); /* returns the numbers that are both in the two lists */ 

    posts.RemoveAll(p => intersection.Contains(p)); /* remove the numbers from 'posts' that are intersected (1, 2, 3 are removed) */ 
+0

Вы даже можете удалить уровень косвенности в последней строке, так как вы можете просто написать: post.RemoveAll (intersection.Contains); 'Нет необходимости создавать анонимный метод, который принимает один аргумент, просто для вызова еще один метод, передавая этот самый аргумент. –

+0

Да, вы правы, я написал так, чтобы было легче понять, что переменная 'p' зацикливается и передается в качестве аргумента в список 'intersection'. –

Смежные вопросы