Вопрос

У меня есть двумерный неровный массив (хотя он всегда прямоугольный), который я инициализирую с помощью традиционного цикла:

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] и присваивание ссылок на это вместо выделения нового массива для каждой строки.Есть ли способ сделать это, не становясь слишком загадочным?

Это было полезно?

Решение

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

Другие советы

То, что у вас есть, не будет работать как new происходит перед вызовом Repeat.Вам нужно что-то, что также повторяет создание массива.Это может быть достигнуто с помощью Enumerable.Range способ чтобы сгенерировать диапазон, а затем выполнить Select операция это сопоставляет каждый элемент диапазона с новым экземпляром массива (как в Ответ Эми Би).

Однако я думаю, что вы пытаетесь использовать LINQ там, где в данном случае это не совсем уместно.То, что у вас было до решения LINQ, просто прекрасно.Конечно, если вам нужен подход в стиле LINQ, подобный Enumerable.Repeat, вы могли бы написать свой собственный метод расширения, который генерирует новый элемент, например:

    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();

Поведение является правильным - Repeat() возвращает последовательность, которая содержит предоставленный объект несколько раз.Вы можете проделать следующий трюк.

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

Вы не можете сделать это с помощью Repeat способ :тот самый element параметр вычисляется только один раз, поэтому на самом деле он всегда повторяет один и тот же экземпляр.Вместо этого вы могли бы создать метод для выполнения того, что вы хотите, который принимал бы лямбда-выражение вместо значения :

    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();

Я только что написал эту функцию...

    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);

О чем

var myArr = new double[rowCount, colCount];

или

double myArr = new double[rowCount, colCount];

Ссылка: http://msdn.microsoft.com/en-us/library/aa691346 (v=против 71).aspx

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top