以 LINQ 方式初始化锯齿状数组

发布于 2024-07-27 13:37:44 字数 444 浏览 6 评论 0原文

我有一个二维锯齿状数组(尽管它始终是矩形),我使用传统循环对其进行初始化:

var myArr = new double[rowCount][];
for (int i = 0; i < rowCount; i++) {
    myArr[i] = new double[colCount];
}

我想也许某些 LINQ 函数可以为我提供一种优雅的方法来在一个语句中执行此操作。 然而,我能想到的最接近的是:

double[][] myArr = Enumerable.Repeat(new double[colCount], rowCount).ToArray();

问题是它似乎正在创建一个 double[colCount] 并分配对该引用的引用,而不是为每行分配一个新数组。 有没有办法做到这一点而又不会变得太神秘?

I have a 2-dimensional jagged array (though it's always rectangular), which I initialize using the traditional loop:

var myArr = new double[rowCount][];
for (int i = 0; i < rowCount; i++) {
    myArr[i] = new double[colCount];
}

I thought maybe some LINQ function would give me an elegant way to do this in one statement. However, the closest I can come up with is this:

double[][] myArr = Enumerable.Repeat(new double[colCount], rowCount).ToArray();

The problem is that it seems to be creating a single double[colCount] and assigning references to that intsead of allocating a new array for each row. Is there a way to do this without getting too cryptic?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

许仙没带伞 2024-08-03 13:37:44
double[][] myArr = Enumerable
  .Range(0, rowCount)
  .Select(i => new double[colCount])
  .ToArray();
double[][] myArr = Enumerable
  .Range(0, rowCount)
  .Select(i => new double[colCount])
  .ToArray();
没有心的人 2024-08-03 13:37:44

您所拥有的内容将不起作用,因为 new 在调用 重复。 您需要能够重复创建数组的东西。 这可以使用 Enumerable.Range 来实现 方法 生成范围,然后执行 选择操作,将范围的每个元素映射到新的数组实例(如艾米 B 的回答)。

但是,我认为您正在尝试使用 LINQ,但在这种情况下这样做并不合适。 在使用 LINQ 解决方案之前所拥有的一切都很好。 当然,如果您想要类似于 Enumerable 的 LINQ 风格方法。重复,你可以编写自己的扩展方法来生成一个新的项目,例如:

    public static IEnumerable<TResult> Repeat<TResult>(
          Func<TResult> generator,
          int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

然后你可以按如下方式调用它:

   var result = Repeat(()=>new double[rowCount], columnCount).ToArray();

What you have won't work as the new occurs before the call to Repeat. You need something that also repeats the creation of the array. This can be achieved using the Enumerable.Range method to generate a range and then performing a Select operation that maps each element of the range to a new array instance (as in Amy B's answer).

However, I think that you are trying to use LINQ where it isn't really appropriate to do so in this case. What you had prior to the LINQ solution is just fine. Of course, if you wanted a LINQ-style approach similar to Enumerable.Repeat, you could write your own extension method that generates a new item, such as:

    public static IEnumerable<TResult> Repeat<TResult>(
          Func<TResult> generator,
          int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

Then you can call it as follows:

   var result = Repeat(()=>new double[rowCount], columnCount).ToArray();
冷︶言冷语的世界 2024-08-03 13:37:44

行为是正确的 - Repeat() 返回一个多次包含所提供对象的序列。 您可以执行以下技巧。

double[][] myArr = Enumerable
    .Repeat(0, rowCount)
    .Select(i => new double[colCount])
    .ToArray();

The behavior is correct - Repeat() returns a sequence that contains the supplied object multiple times. You can do the following trick.

double[][] myArr = Enumerable
    .Repeat(0, rowCount)
    .Select(i => new double[colCount])
    .ToArray();
离不开的别离 2024-08-03 13:37:44

您不能使用 Repeat 方法来做到这一点:element 参数仅计算一次,因此它实际上总是重复相同的实例。 相反,您可以创建一个方法来执行您想要的操作,该方法将采用 lambda 而不是值:

    public static IEnumerable<T> Sequence<T>(Func<T> generator, int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

    ...

    var myArr = Sequence(() => new double[colCount], rowCount).ToArray();

You can't do that with the Repeat method : the element parameter is only evaluated once, so indeed it always repeats the same instance. Instead, you could create a method to do what you want, which would take a lambda instead of a value :

    public static IEnumerable<T> Sequence<T>(Func<T> generator, int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return generator();
        }
    }

    ...

    var myArr = Sequence(() => new double[colCount], rowCount).ToArray();
橙幽之幻 2024-08-03 13:37:44

我刚刚写了这个函数......

    public static T[][] GetMatrix<T>(int m, int n)
    {
        var v = new T[m][];
        for(int i=0;i<m; ++i) v[i] = new T[n];
        return v;
    }

似乎有效。

用法:

float[][] vertices = GetMatrix<float>(8, 3);

I just wrote this function...

    public static T[][] GetMatrix<T>(int m, int n)
    {
        var v = new T[m][];
        for(int i=0;i<m; ++i) v[i] = new T[n];
        return v;
    }

Seems to work.

Usage:

float[][] vertices = GetMatrix<float>(8, 3);
只有一腔孤勇 2024-08-03 13:37:44

怎么样

var myArr = new double[rowCount, colCount];

double myArr = new double[rowCount, colCount];

参考:http://msdn.microsoft .com/en-us/library/aa691346(v=vs.71).aspx

What about

var myArr = new double[rowCount, colCount];

or

double myArr = new double[rowCount, colCount];

Reference: http://msdn.microsoft.com/en-us/library/aa691346(v=vs.71).aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文