我需要从HttpSession集合中删除项目。在以下代码中,myList包含与Session相同的项目。如果myList / Session中的项目不在itemsToRemove中,则应从会话集合中删除它们。
但是,我不确定lambda语法应该是什么样子。以下内容并不正确。
myList.ForEach(x => !itemsToRemove.Contains(x) { Session.Remove(x) });
我是如何使用lambda表达式将所有内容放在一行来完成此任务的?
另外,有没有办法避免创建中间列表(myList)?我之所以这样做,是因为我无法在迭代过程中从会话中删除项目。
答案 0 :(得分:7)
最天真的方式:
myList.Where(x => !itemsToRemove.Contains(x)) // LINQ extension method
.ToList() <----
.ForEach(x => Session.Remove(x)); // List<T> method so this is required |
你也可以使用它:
mystList.Except(itemsToRemove)
.ToList()
.ForEach(x => Session.Remove(x));
但要使用ForEach
,基础类型应为List<T>
,因此您需要先调用ToList()
。是什么导致整个集合的过度枚举。
我会这样做:
foreach (var x in mystList.Except(itemsToRemove))
{
Session.Remove(x)
}
这将最大限度地减少枚举次数。
答案 1 :(得分:0)
首先,abatischev的回答非常好。从性能角度和可读性角度来看,它是理想的。但是,如果您真的想要将所有功能都塞进一个语句中(我不建议这样做),您可以尝试以下方法:
Session.OfType<string>()
.Except(itemsToRemove)
.ToList()
.ForEach(x => Session.Remove(x));
正如abatischev所见,ToList()
调用会在整个集合中花费额外的枚举,如果集合中包含大量元素,则可能会产生非常重要的性能影响。但是,这意味着ForEach()
调用会迭代新创建的List<string>
,它会填充您myList
的角色,并允许您从会话中删除项目(因为您正在迭代该临时列表,而不是会话。)
(注意我自己没有使用HttpSessionState对象,只看了他们的MSDN文章。如果字符串不是HttpSessionState所持有的,你可能需要用其他东西替换string
泛型类型。)