使用foreach而不是for?循环使用c#中的锯齿状数组?

时间:2013-02-14 15:08:11

标签: c# arrays loops for-loop foreach

我正在处理一个项目,我发现自己使用嵌套的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中的正确位置?这样做会有什么好处/损失(如果可能的话),除了稍微整洁的代码之外?

5 个答案:

答案 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);
}

我只是坚持使用嵌套循环。