替代for循环遍历数组的方法是什么?

12

我喜欢Python中的列表推导式,因为它们简洁地表示了对列表的转换。

然而,在其他语言中,我经常会写出类似以下的代码:

foreach (int x in intArray)
  if (x > 3) //generic condition on x
    x++ 
    //do other processing

这个示例是用C#编写的,我认为LINQ可以帮助解决这个问题,但是是否有一些常见的编程结构可以替换这个稍微不太优雅的解决方案?也许有一些数据结构我没有考虑到吗?

6个回答

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));

2
在C#中,您可以像这样对IEnumerable中的任何内容应用选择性处理:
intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));

Etc..


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]

0
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))

0

在Ruby中:

intArray.select { |x| x > 3 }.each do |x|
  # do other processing
end

或者如果“其他处理”只是一个简短的一行:

intArray.select { |x| x > 3 }.each { |x| something_that_uses x }

最后,如果你想返回一个新的数组,其中包含那些大于3的元素经过处理后的结果:
intArray.select { |x| x > 3 }.map { |x| do_something_to x }

-1

根据语言和需要做什么,许多语言中所谓的“map”可能是您要寻找的东西。我不了解C#,但根据this页面,.NET 2.0将map称为“ConvertAll”。

“map”的含义非常简单-取一个列表,并对其每个元素应用一个函数,返回一个新列表。您可能还在寻找“filter”,它会给您一个满足另一个列表中谓词的项目列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接