如何用LINQ遍历一次可枚举集合,拆分奇偶元素并存入元组?
如何用LINQ遍历一次集合并拆分奇偶到元组?
当然可行!而且完全可以做到只遍历一次集合,用LINQ的Aggregate方法就能完美解决这个问题,咱们一步步来理清楚:
核心思路:用累积操作实现单次遍历
要避免多次遍历集合,关键是在遍历过程中实时累积奇偶元素,而不是事后再分别过滤(两次Where会触发两次集合遍历)。Aggregate方法正好是为这种"累积状态"的场景设计的——它会遍历每个元素一次,用一个累积器对象保存中间状态,最后返回最终的累积结果。
正确实现代码
针对你的输入[1,2,3,4],可以这样写:
var input = new List<int> { 1, 2, 3, 4 }; // 用Aggregate累积奇偶列表,最后解构到元组 var (odds, evens) = input.Aggregate( // 初始化累积器:包含两个空列表的元组 (Odds: new List<int>(), Evens: new List<int>()), // 遍历每个元素时更新累积器 (accumulator, currentNum) => { if (currentNum % 2 == 1) accumulator.Odds.Add(currentNum); else accumulator.Evens.Add(currentNum); return accumulator; } ); // 输出结果:odds = [1,3], evens = [2,4]
你的原有代码问题分析
你原来的查询表达式逻辑有个关键错误:
(rez1,rez2)=from value in Generator() let odds=Enumerable.Empty<Elem>() let evens=Enumerable.Empty<Elem>() select(value%2==0?odds.append(value):odds.append(value))
这里的let odds=Enumerable.Empty<Elem>()是每个元素遍历都会重新初始化一次空集合,每次select返回的都是只包含当前元素的新集合,完全没有累积之前的元素,所以根本无法得到所有奇偶元素的集合。
额外说明:如果想用查询表达式?
其实查询表达式更适合做过滤、投影这类无状态的操作,不太适合这种需要累积状态的场景。如果一定要用查询表达式,也得结合Aggregate,但写法会很别扭,不如直接用Aggregate的方法语法清晰。
内容的提问来源于stack exchange,提问作者Bercovici Adrian
相关产品推荐
相关产品推荐

