4

我正在做一个项目,我发现自己使用嵌套for循环反复循环一个锯齿状数组。我想知道是否有一种更简洁的方式来使用它foreach

这就是我的意思:

for (int ii = 0; ii < xDimension; ii++)
  {
    for (int jj = 0; jj < yDimension; jj++)
      {
        OutputArray[ii][jj] = someFunction(InputArray[ii][jj]);
      }
  }

请注意,即使我的数据是固定大小的,我也在使用锯齿状数组,因为锯齿状数组比多维数组更快。不幸的是,速度是这个项目的一个问题,所以不幸的是,性能将超过我自己的强迫症编码需求。

有没有办法foreach避免嵌套for循环,但将输出数据放在正确的位置OutputArray?除了稍微整洁的代码之外,这样做(如果可能的话)是否会有任何好处/损失?

4

5 回答 5

3

如果你真的想创建一个锯齿状数组作为结果,你可以使用Array.ConvertAll两次:

var result = Array.ConvertAll(input,
                              array => Array.ConvertAll(array, SomeFunction));

这比使用LINQ中的Select/稍微高效一些,因为它知道它将一个数组转换为另一个数组,因此可以立即创建目标数组。使用后跟需要逐步建立结果,就好像您将它们放入 a中一样,在缓冲区耗尽时复制它们 - 然后在最后“调整大小”数组。ToArraySelectToArrayList<T>

另一方面,这些天使用 LINQ(根据 Daniel 的回答)可能会更加惯用......而且性能差异通常是微不足道的。我想我会把它作为另一种选择:)

(请注意,这会创建新数组,忽略现有的OutputArray......我假设你可以摆脱现有的创建OutputArray,尽管情况可能并非如此......)

于 2013-02-14T15:17:22.757 回答
2

以下代码“更整洁”:

OutputArray = InputArray.Select(x => x.Select(y => someFunction(y)).ToArray())
                        .ToArray();

但我只会使用循环,因为这个 LINQ 版本有一个明显的缺点:它创建新数组而不是使用OutputArray. OutputArray如果您在向我们展示的循环之前创建,则此论点没有实际意义。
此外,它很难阅读。

于 2013-02-14T15:14:18.030 回答
1

您可以使用 a 更轻松地从锯齿状数组中获取数据foreach,但是由于没有指示索引的变量,因此您无法像在示例中那样非常有效地设置数组的值。

如果您只是想读取这些值,您可以这样做:

foreach(int n in OutputArray.SelectMany(array=>array))
{
    Console.WriteLine(n);
}

需要将SelectMany序列展平,以便它不是序列序列,而是单个序列。

于 2013-02-14T15:12:45.317 回答
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循环结构更易于维护。

于 2013-02-14T15:19:44.743 回答
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);
}

不过,我会坚持使用嵌套循环。

于 2013-02-14T15:22:10.550 回答