我喜欢Python中的列表推导,因为它们简洁地表示了列表的转换。
然而,在其他语言中,我经常发现自己写的东西是:
foreach (int x in intArray)
if (x > 3) //generic condition on x
x++
//do other processing
这个例子在C#中,我的印象是LINQ可以帮助解决这个问题,但是有一些常见的编程结构可以取代这个稍微不那么优雅的解决方案吗?也许是我不考虑的数据结构?
答案 0 :(得分:5)
原始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));
答案 1 :(得分:2)
在C#中,您可以对IEnumerable中的任何内容应用选择性处理,如下所示:
intArray.Where(i => i > 3).ConvertAll();
DoStuff(intArray.Where(i => i 3));
等。
答案 2 :(得分:1)
在Python中,你有filter and map,这可以是你想要的:
map(lambda x: foo(x + 1) filter(lambda x: x > 3, intArray))
还有list comprehensions可以在一个简单的陈述中做到这两点:
[f(x + 1) for x in intArray if x > 3]
答案 3 :(得分:0)
:
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 }
答案 4 :(得分:0)
map(lambda x: test(x + 1) filter(lambda x: x > 3, arr))
答案 5 :(得分:-1)
取决于语言和你需要做什么,一个“地图”,因为它以多种语言调用,可能是你正在寻找的。我不知道C#,但根据this页面,.NET 2.0调用map“ConvertAll”。
“map”的含义非常简单 - 获取一个列表,并将函数应用于它的每个元素,返回一个新列表。您可能还在寻找“过滤器”,它会为您提供满足另一个列表中谓词的项目列表。