我正在开发Silverlight 2/3应用程序。我想使用List.RemoveAll(或者它可能是IList.RemoveAll?)并指定一个谓词,以便我可以在一次扫描中从列表中删除一堆元素。
但是,Silverlight中似乎不存在此功能。我在这里错过了什么吗?是否有另一种方法同样容易?现在,我手动在foreach中迭代我的元素并保留第二个列表(因为你在迭代时不能删除),而且它非常麻烦。
答案 0 :(得分:3)
您可以使用LINQ,如:
list = list.Where(predicate).ToList();
另一种方法是删除for循环中的元素:
for (int i = list.Count - 1; i >= 0; --i)
if (predicate(list[i]))
list.RemoveAt(i);
答案 1 :(得分:3)
如果你真正需要的是访问子集,那么实际上没有理由去删除,只需访问这样的子集:
而不是(可能:
List<string> subSet = l.RemoveAll ( p => !p.StartsWith ("a") );
得到相反的结果:
List<string> l = new List<string> () { "a", "b", "aa", "ab" };
var subSet = l.Where ( p => p.StartsWith ( "a" ) );
<小时/> 好的,但要真正删除它们(假设与上面相同的起始列表):
l.Where ( p => p.StartsWith ( "a" ) ).ToList ().ForEach ( q => l.Remove ( q ) );
。在System.Linq中IEnumerable上有一个扩展方法。 因此,只要您的列表是通用IEnumerable(并且您已添加使用),它就应该可用。
答案 2 :(得分:2)
我和Mehrdad在一起,扩展方法可以解决这个问题。为了给你完整的签名,这里是:
/// <summary>
/// Removes all entries from a target list where the predicate is true.
/// </summary>
/// <typeparam name="T">The type of item that must exist in the list.</typeparam>
/// <param name="list">The list to remove entries from</param>
/// <param name="predicate">The predicate that contains a testing criteria to determine if an entry should be removed from the list.</param>
/// <returns>The number of records removed.</returns>
public static int RemoveAll<T>(this IList<T> list, Predicate<T> predicate)
{
int returnCount = 0;
for (int i = list.Count - 1; i >= 0; --i)
{
if (predicate(list[i]))
{
list.RemoveAt(i);
returnCount++;
}
}
return returnCount;
}