Инициализировать неровный массив способом LINQ
у меня есть 2-мерный зубчатый массив (хотя он всегда прямоугольный), который я инициализирую с помощью традиционного цикла:
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]
и назначение ссылок на этот intsead выделения нового массива для каждой строки. Есть ли способ сделать это не слишком загадочно?
6 ответов
то, что у вас не будет работать как 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
метод: оценивается только один раз, поэтому он всегда повторяет один и тот же экземпляр. Вместо этого вы можете создать метод для выполнения того, что хотите, который будет принимать лямбда вместо значения :
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