从集合中查找和删除项目 [英] Find And Remove Items From Collection
问题描述
从集合中删除集合,但仍将删除的项目保留在单独的集合中的最佳方法是什么?
What is the best way to remove a set from a collection, but still keep the items that were removed in a separate collection?
我已经写了一个扩展方法来做到这一点,但是我认为必须有一个更好的方法.这是我的功能:
I have written an extension method that does that, but I think there must be a better way. Here is my function:
public static List<T> FindAndRemove<T>(this List<T> lst, Predicate<T> match)
{
List<T> ret = lst.FindAll(match);
lst.RemoveAll(match);
return ret;
}
您将像这样使用它:
List<String> myList = new List<String>();
myList.Add("ABC");
myList.Add("DEF");
myList.Add("ABC");
List<String> removed = myList.FindAndRemove(x => x == "ABC");
// myList now contains 1 item (DEF)
// removed now contains 2 items (ABC, ABC)
我不确定100%地了解FindAll
和RemoveAll
方法在幕后发生了什么,但是我认为更好的方法是将项目从一个列表转移"到另一个列表.
I'm not 100% sure what goes on behind the scenes in the FindAll
and RemoveAll
methods, but I imagine a better way would be to somehow "transfer" items from one list to the other.
推荐答案
Op的答案是迄今为止提出的和建议的解决方案中最好的.这是我机器上的时间:
Op's answer is the best out of the proposed and suggested solutions so far. Here are timings on my machine:
public static class Class1
{
// 21ms on my machine
public static List<T> FindAndRemove<T>(this List<T> lst, Predicate<T> match)
{
List<T> ret = lst.FindAll(match);
lst.RemoveAll(match);
return ret;
}
// 538ms on my machine
public static List<T> MimoAnswer<T>(this List<T> lst, Predicate<T> match)
{
var ret = new List<T>();
int i = 0;
while (i < lst.Count)
{
T t = lst[i];
if (!match(t))
{
i++;
}
else
{
lst.RemoveAt(i);
ret.Add(t);
}
}
return ret;
}
// 40ms on my machine
public static IEnumerable<T> GuvanteSuggestion<T>(this IList<T> list, Func<T, bool> predicate)
{
var removals = new List<Action>();
foreach (T item in list.Where(predicate))
{
T copy = item;
yield return copy;
removals.Add(() => list.Remove(copy));
}
// this hides the cost of processing though the work is still expensive
Task.Factory.StartNew(() => Parallel.ForEach(removals, remove => remove()));
}
}
[TestFixture]
public class Tester : PerformanceTester
{
[Test]
public void Test()
{
List<int> ints = Enumerable.Range(1, 100000).ToList();
IEnumerable<int> enumerable = ints.GuvanteSuggestion(i => i % 2 == 0);
Assert.That(enumerable.Count(), Is.EqualTo(50000));
}
}
这篇关于从集合中查找和删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!