我正在处理一个项目,我发现自己使用嵌套的for
循环反复循环一个锯齿状数组。我想知道是否有更简洁的方式使用foreach
进行此操作?
这就是我的意思:
for (int ii = 0; ii < xDimension; ii++)
{
for (int jj = 0; jj < yDimension; jj++)
{
OutputArray[ii][jj] = someFunction(InputArray[ii][jj]);
}
}
请注意,我使用Jagged数组,即使我的数据是固定大小的,因为锯齿状数组比多维数组快。不幸的是,速度是这个项目的一个问题,所以不幸的是,性能将超过我自己的OCD编码需求。
有没有办法用foreach
来避免嵌套的for
循环但是将输出数据放在OutputArray
中的正确位置?这样做会有什么好处/损失(如果可能的话),除了稍微整洁的代码之外?
答案 0 :(得分:3)
如果您真的想要创建一个锯齿状数组,可以使用Array.ConvertAll
两次:
var result = Array.ConvertAll(input,
array => Array.ConvertAll(array, SomeFunction));
这比使用LINQ中的Select
/ ToArray
稍微有效一点,因为知道它正在将数组转换为另一个数组,因此可以立即创建目标数组。使用Select
后跟ToArray
需要逐步构建结果,就好像将它们放入List<T>
,在缓冲区耗尽时复制它们 - 然后“正确调整大小” “最后的阵列。
另一方面,使用LINQ(根据丹尼尔的回答)这些天可能会更加惯用......而且性能差异通常无关紧要。我以为我会把它作为另一种选择:)
(请注意,这会创建新数组,忽略现有的OutputArray
...我假设您可以摆脱现有OutputArray
的创建,尽管可能并非如此。 ..)
答案 1 :(得分:2)
以下代码为“neater”:
OutputArray = InputArray.Select(x => x.Select(y => someFunction(y)).ToArray())
.ToArray();
但我会选择循环,因为这个LINQ版本有一个明显的缺点:它创建新的数组而不是使用OutputArray
中的现有数组。如果你在向我们展示的循环之前创建OutputArray
,那么这个论点是没有意义的
此外,阅读起来要困难得多。
答案 2 :(得分:1)
您可以使用foreach
更轻松地获取锯齿状数组的数据 ,但由于您没有指示索引的变量,因此您将无法非常有效地设置数组的值,就像在您的示例中一样。
如果你只想读取值,你可以这样做:
foreach(int n in OutputArray.SelectMany(array=>array))
{
Console.WriteLine(n);
}
需要SelectMany
来平整序列,因此它不是一个序列序列,而只是一个序列。
答案 3 :(得分:0)
您甚至可以使用LINQ获取索引:
foreach (var t in InputArray.SelectMany(
(inner, ii) => inner.Select((val, jj) => new { val, ii, jj })))
{
OutputArray[t.ii][t.jj] = someFunction(t.val);
}
但是,老实说,双 - for
- 循环结构更易于维护。
答案 4 :(得分:0)
另一种选择,只是为了好玩:
foreach (var item in InputArray.SelectMany(x => x).Select((value, index) => new {value, index}))
{
var x = item.index / yDimension;
var y = item.index % yDimension;
OutputArray[x][y] = someFunction(item.value);
}
我只是坚持使用嵌套循环。