Ответ 1
Я бы попробовал ответить @Mehrdad и, возможно, протестировал его и против этого...
var selected = items.Where(item => item.Something > 10).ToList();
selected.ForEach(item => items.Remove(item));
otherList.AddRange(selected);
Каков предпочтительный способ переноса некоторых элементов (не всех) из одного списка в другой.
Я делаю следующее:
var selected = from item in items
where item.something > 10
select item;
otherList.AddRange(selected);
items.RemoveAll(item => selected.Contains(item));
В интересах наличия самого быстрого/лучшего кода есть ли лучший способ?
Я бы попробовал ответить @Mehrdad и, возможно, протестировал его и против этого...
var selected = items.Where(item => item.Something > 10).ToList();
selected.ForEach(item => items.Remove(item));
otherList.AddRange(selected);
Я предлагаю:
var selected = items.Where(item => item.Something > 10).ToList();
items = items.Except(selected).ToList();
otherList.AddRange(selected);
Это довольно плохая производительность - она фактически перечисляет запрос n раз (для n элементов в items
). Было бы лучше, если бы вы построили (например) HashSet<T>
элементов для управления.
Чтобы дать простой пример только с int
значениями:
var items = new List<int> { 1, 2, 3, 4, 5, 6 };
var otherList = new List<int>();
var selected = new HashSet<int>(items.Where(
item => item > 3));
otherList.AddRange(selected);
items.RemoveAll(selected.Contains);
RemoveAll проходит через каждый элемент и каждый раз перечисляет все значения выбранного вами списка. Это займет больше времени, чем нужно...
Я бы поставил условие непосредственно в параметр RemoveAll:
items.RemoveAll(item => item.something > 10);
Если вы сделаете это и не измените остальную часть кода, будет дублирование кода, что не очень хорошо. Я бы сделал следующее, чтобы избежать этого:
Func<ItemType, bool> selectedCondition = (item => item.something > 10);
otherList.AddRange(items.Where(selectedCondition));
items.RemoveAll(new Predicate<ItemType>(selectedCondition));
Как насчет раздела:
int[] items = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var partition = items.ToLookup(x => x > 5);
var part1 = partition[true];
var part2 = partition[false];