2012-03-27 3 views
8

Чтобы присвоить определенное значение для 1D массива я использую LINQ, как так:2D-массив. Установите все значения в определенное значение

 int[] nums = new int[20]; 
     nums = (from i in nums select 1).ToArray<int>(); 
     nums[0] = 2; 

Существует подобный способ сделать это в 2D ([х, у]) массив? Или короткий путь, без использования вложенных циклов?

+5

вы не устанавливая значения в массиве, ваше создание * новый * массив – vidstige

ответ

6

LINQ не работает особенно хорошо с многомерными массивами.

Зубчатые массивы не так уж плохо:

var array = Enumerable.Range(0, 10) 
         .Select(x => Enumerable.Repeat('x', 10).ToArray()) 
         .ToArray(); 

... но прямоугольные массивы не имеют какой-либо конкретной поддержки. Просто используйте циклы.

(. Обратите внимание на использование Enumerable.Repeat как несколько проще подход к созданию 1-мерный массив, кстати)

+0

Это не то, что мне нужно, это массив внутри массива. –

1

Один из способов вы можете сделать это следующим образом:

// Define a little function that just returns an IEnumerable with the given value 
static IEnumerable<int> Fill(int value) 
{ 
    while (true) yield return value; 
} 

// Start with a 1 dimensional array and then for each element create a new array 10 long with the value of 2 in 
var ar = new int[20].Select(a => Fill(2).Take(10).ToArray()).ToArray(); 
+0

Спасибо, но это массив внутри массива. Я ищу способ сделать это в 2D-массиве [x, y] –

5

Если вы действительно хотят, чтобы избежать вложенных циклов, вы можете использовать только один цикл:

int[,] nums = new int[x,y]; 
for (int i=0;i<x*y;i++) nums[i%x,i/x]=n; 

вы можете сделать это проще, бросив его в какую-то функцию в полезности класса:

public static T[,] GetNew2DArray<T>(int x, int y, T initialValue) 
{ 
    T[,] nums = new T[x, y]; 
    for (int i = 0; i < x * y; i++) nums[i % x, i/x] = initialValue; 
    return nums; 
} 

И использовать его как это:

int[,] nums = GetNew2DArray(5, 20, 1); 
+0

Хорошая идея, но мне это слишком сложно. Я ищу простую вещь, такую ​​как LINQ. –

+2

Первые две (TWO !!) строки кода в этом ответе решают вашу проблему. Я компактное форматирование и выгляжу уродливым, но вы не можете получить ничего проще, меньше и быстрее. – heltonbiker

+0

будет ли такой одиночный for-loop быстрее по сравнению с вложенным for-loop? – juFo

3

Ну, это может быть обман, потому что она просто перемещает зацикливание код в метод расширения, но это не позволяет инициализировать 2D массив в один значение просто и в порядке, аналогичном тому, как вы можете инициализировать 1D-массив для одного значения.

Во-первых, как уже упоминалось Джон Скит, вы можете очистить ваш пример инициализации 1D массив так:

int [] numbers = Enumerable.Repeat(1,20).ToArray(); 

С моим методом расширения, вы будете иметь возможность инициализировать 2D массив следующим образом:

public static T[,] To2DArray<T>(this IEnumerable<T> items, int rows, int columns) 
{ 
    var matrix = new T[rows, columns]; 
    int row = 0; 
    int column = 0; 

    foreach (T item in items) 
    { 
     matrix[row, column] = item; 
     ++column; 
     if (column == columns) 
     { 
      ++row; 
      column = 0; 
     } 
    } 

    return matrix; 
} 
+0

Нет причин для того, чтобы этот метод расширения не был общим, я обновил его соответствующим образом. –

1

Могу ли я предложить новый метод расширения.

public static class TwoDArrayExtensions 
{ 
    public static void ClearTo(this int[,] a, int val) 
    { 
     for (int i=a.GetLowerBound(0); i <= a.GetUpperBound(0); i++) 
     { 
      for (int j=a.GetLowerBound(1); j <= a.GetUpperBound(1); j++) 
      { 
       a[i,j] = val; 
      } 
     } 
    } 
} 

Используйте это так:

var nums = new int[10, 10]; 
nums.ClearTo(1); 
Смежные вопросы