将某些项目(并非所有项目)从一个列表转移到另一个列表的首选方法是什么。
我正在做的是以下内容:
var selected = from item in items
where item.something > 10
select item;
otherList.AddRange(selected);
items.RemoveAll(item => selected.Contains(item));
为了获得最快/最好的代码,还有更好的方法吗?
答案 0 :(得分:17)
我会尝试@ Mehrdad的答案,也许也可以针对这个问题进行测试......
var selected = items.Where(item => item.Something > 10).ToList();
selected.ForEach(item => items.Remove(item));
otherList.AddRange(selected);
答案 1 :(得分:12)
我建议:
var selected = items.Where(item => item.Something > 10).ToList();
items = items.Except(selected).ToList();
otherList.AddRange(selected);
答案 2 :(得分:7)
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));
答案 3 :(得分:6)
这是非常糟糕的性能 - 它实际上枚举了一次查询n次(对于items
中的n个项目)。如果您构建(例如)要操作的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);
答案 4 :(得分:1)
分区怎么样:
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];