Выражение Lambda или LinQ для удаления определенных объектов из списка - PullRequest
2 голосов
/ 15 июля 2011

У меня есть корзина. Список строк и я хочу удалить все элементы, где количество == 0

Это список, содержащий коллекцию объектов CartLine:

public class Cart
{
    private IList<CartLine> lines = new List<CartLine>();
    public IList<CartLine> Lines { get { return lines; } set { lines = value; } }
}   

public class CartLine
{
    Product Product {get; set;}
    int Quantity {get; set;}

}

Так что-то вроде:

cart.Lines.RemoveAll(x => x.Quantity == 0)

Я получаю только Remove и RemoveAt, а не RemoveAll!

Также нельзя удалить в цикле foreach, получить ошибку: Коллекция была изменена; операция перечисления может не выполняться.

Мне уже удалось сделать это с помощью этого кода, наверняка должно быть что-то более эффективное?

var myList = cart.Lines.ToList();
myList.RemoveAll(x => x.Quantity == 0);
cart.Lines = myList;

Хорошо, проблема решена! Спасибо, ребята, вот что она делает:

cart.Lines = cart.Lines.Where (x => x.Quantity! = 0);

Ответы [ 6 ]

6 голосов
/ 15 июля 2011

Если Lines - List<T>, то самый простой способ - просто написать:

cart.Lines.RemoveAll(x => x.Quantity == 0);

Если Lines равен IEnumerable<T>, вы можете выбрать отрицательный (как предложил Влад) - вы также можете изменить список, используя ToList(), а затем сделать RemoveAll(), но это будет излишним.

cart.Lines = cart.Lines.Where(x => x.Quantity != 0);

UPDATE:

Так как вы сказали, что Lines - это IList<T>, вам нужно выбрать негатив и преобразовать в список, например:

cart.Lines = cart.Lines.Where(x => x.Quantity != 0).ToList();

Или вы можете преобразовать в List<T>, используя ToList(), затем позвонить RemoveAll() и затем сохранить обратно:

var temp = cart.Lines.ToList();
temp.RemoveAll(x => x.Quantity != 0);
cart.Lines = temp;

Между прочим, в качестве FYI я рассчитывал как создание списка удалений, так и затем Remove() против выбора отрицательного значения с помощью Where() и вызова ToList(), и комбинация Where / ToList была намного быстрее, что имеет смысл, поскольку оба выделяют память , но Where / ToList значительно меньше тасует память.

Вот время для удаления всех четных чисел из списка в 100 000 дюймов:

  • Удаление всех событий, создание списка удаления и вызов Remove () для каждого заняло: 3921 мс
  • Удаление всех событий с помощью Where () на отрицательном, а затем ToList () заняло: 2 мс
  • Удаление всех событий с помощью ToList () на оригинале, затем RemoveAll () заняло: 1 мс
3 голосов
/ 15 июля 2011

Предполагая, что cart.Lines является списком <>: cart.Lines.RemoveAll(x => x.Quantity == 0);

1 голос
/ 15 июля 2011

Я отправлю свое предложение по этой проблеме.

private IList<CartLine> lines = new List<CartLine>(); 

должно быть:

private List<CartLine> lines = new List<CartLine>(); 

Это позволит вам использовать предложенный метод:

cart.Lines.RemoveAll(x => x.Quantity == 0);  

Вы делаете именно это, делая так:

var myList = cart.Lines.ToList();       
myList.RemoveAll(x => x.Quantity == 0);              
cart.Lines = myList;   
1 голос
/ 15 июля 2011

Эти запросы в основном имеют приоритет над списком, и, как вы знаете, вы не должны использовать их для непосредственного изменения списка. Скорее вы должны составить список элементов, которые будут удалены с помощью запроса, а затем удалить их в отдельной операции.

EDIT:

да, я забыл, что вы можете использовать RemoveAll, чтобы сделать это в одной строке: D

1 голос
/ 15 июля 2011
var myResult = cart.Lines.Where(x => x.Quantity > 0)

В качестве альтернативы вы можете использовать RemoveAll

cart.Lines.RemoveAll(x => x.Quantity == 0)

Отметьте этот пост, который отвечает на ваш вопрос C #, используя LINQ для удаления объектов из списка

0 голосов
/ 15 июля 2011

Вы можете сделать это следующим образом:

Cart cart = new Cart();
List<CartLine> cartLines = cart.Lines.ToList<CartLine>();
cartLines.RemoveAll(x => x.Quantity == 0);
cart.Lines = cartLines;

Кроме того, вы должны установить количество корзин и свойства продукта как общедоступные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...