替换为...,如果数组迭代

时间:2020-03-05 18:40:06  来源:igfitidea点击:

我喜欢Python中的列表理解,因为它们简洁地表示了列表的转换。

但是,在其他语言中,我经常发现自己按照以下方式写东西:

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

这个例子是在C#中,我对LINQ的印象很深,但是有一些通用的编程构造可以代替这个略逊于优雅的解决方案吗?也许我没有考虑的数据结构?

解决方案

回答

取决于语言和我们需要执行的操作,在许多语言中调用的"地图"可能就是我们想要的。我不知道C#,但是根据此页面,.NET 2.0调用映射为" ConvertAll"。

" map"的含义非常简单,只需获取一个列表,然后对每个元素应用一个函数,即可返回新列表。我们可能还会在寻找"过滤器",该过滤器将为我们提供满足另一个列表中的谓词的项目列表。

回答

在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 }

回答

在Python中,我们具有过滤器和映射,可以根据需要进行过滤:

map(lambda x: foo(x + 1) filter(lambda x: x > 3, intArray))

还有一个列表理解可以在一个简单的语句中完成:

[f(x + 1) for x in intArray if x > 3]

回答

在C中,我们可以对IEnumerable中存在的任何内容应用选择性处理,如下所示:

intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));

等等..

回答

原始的" 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));