数组迭代中 for... if 的替代方法
我非常喜欢Python中的列表推导式,因为它能简洁地表示对列表的转换。
不过,在其他编程语言中,我经常会写一些类似于下面这样的代码:
foreach (int x in intArray)
if (x > 3) //generic condition on x
x++
//do other processing
这个例子是用C#写的,我觉得LINQ可以帮助解决这个问题,但有没有什么常见的编程结构可以替代这个稍显笨拙的解决方案呢?也许还有我没有考虑到的数据结构?
6 个回答
1
在Python中,你可以使用 filter 和 map,它们可以帮你完成你想要的操作:
map(lambda x: foo(x + 1) filter(lambda x: x > 3, intArray))
还有 列表推导式,它可以在一个简单的语句中同时完成这两项功能:
[f(x + 1) for x in intArray if x > 3]
2
在C#中,你可以对任何在IEnumerable里面的东西进行选择性处理,方法是这样的:
intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));
等等……
7
在原来的 foreach
循环中,增加的值不会影响数组的内容,想要改变数组的内容,唯一的方法还是使用 for
循环:
for(int i = 0; i < intArray.Length; ++i)
{
if(intArray[i] > 3) ++intArray[i];
}
Linq 不是用来修改现有集合或序列的。它是基于已有的序列创建新的序列。虽然可以用 Linq 实现上面的代码,但这有点偏离了它的初衷:
var newArray1 = from i in intArray select ((i > 3) ? (i + 1) : (i));
var newArray2 = intArray.Select(i => (i > 3) ? (i + 1) : (i));
使用 where
(或者类似的方式),就像其他一些回答中提到的,会把结果序列中小于或等于 3 的值排除掉。
var intArray = new int[] { 10, 1, 20, 2 };
var newArray = from i in intArray where i > 3 select i + 1;
// newArray == { 11, 21 }
数组上有一个 ForEach
方法,可以让你使用一个 lambda 函数来代替 foreach
块,不过如果需要做的事情超过简单的方法调用,我建议还是用 foreach
。
intArray.ForEach(i => DoSomething(i));