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

然而,在其他语言中,我经常发现自己写的东西类似于:

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

这个例子是用 C# 编写的,我的印象是 LINQ 可以帮助解决这个问题,但是是否有一些常见的编程结构可以取代这个稍微不太优雅的解决方案?也许是我没有考虑的数据结构?

有帮助吗?

解决方案

原来的增量 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));

其他提示

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

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

ETC..

在Python中,你有 过滤器和地图, ,这可以是你想要的:

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

还有 列表推导式 它可以用一个简单的语句来完成这两个任务:

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

在红宝石中:

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 }
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))

根据语言和您需要做什么,在许多语言中所谓的“地图”可能就是您正在寻找的东西。我不懂 C#,但根据 页面,.NET 2.0 调用映射“ConvertAll”。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top