2010-06-04 5 views
10

Предположим, у вас есть массив, как:Получение двойной [] строки массив двойной [,] прямоугольный массив

double[,] rectArray = new double[10,3]; 

Теперь вы хотите Fouth строку как двойной [] массив из 3 элементов, не делая:

double[] fourthRow = new double[]{rectArray[3,0], 
            rectArray[3,1], 
            rectArray[3,2]}; 

Возможно ли это каким-то образом? Даже используя подход маршала.

Спасибо!

+0

Мышление на C++ при использовании C# - боль. Как мне интересно решение без копирования или неровного массива ... –

ответ

1

Возможно, вы захотите использовать зубчатый массив. Это не массив из 10 на 3, а массив массивов.

Что-то вроде:

 double[][] rectArray; 
     .... 
     double [] rowArray = rectArray[3]; 

Есть много мест, чтобы узнать больше о зазубренных массивах. Например Dynamically created jagged rectangular array

+1

Мне нужен прямоугольный массив, извините. – abenci

+1

Хорошо ... но вы описываете задачу, которую хотите сделать, которая имеет больше смысла с зубчатым массивом. (Которые часто бывают быстрее и меньше). – Hogan

+0

-1: Не ответил на вопрос. – AMissico

15

Вы можете использовать Buffer.BlockCopy метод:

const int d1 = 10; 
const int d2 = 3; 
const int doubleSize = 8; 

double[,] rectArray = new double[d1, d2]; 
double[] target = new double[d2]; 

int rowToGet = 3; 
Buffer.BlockCopy(rectArray, doubleSize * d2 * rowToGet, target, 0, doubleSize * d2); 
+0

Единственный оптимизированный ответ! – georgiosd

1

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

double[] fourthRow = GetRow(rectArray, 3); 

public static T[] GetRow<T>(T[,] matrix, int row) 
{ 
    var columns = matrix.GetLength(1); 
    var array = new T[columns]; 
    for (int i = 0; i < columns; ++i) 
     array[i] = matrix[row, i]; 
    return array; 
} 
+2

доходность возврата будет отличной с таким подходом –

11

LINQ к спасению:

var s = rectArray.Cast<double>().Skip(9).Take(3).ToArray(); 

Объяснение: Cas ting многомерный массив выравнивает его до одномерного массива. После этого все, что нам нужно сделать, это пропустить элемент, который мы хотим (4-й элемент в 2-D массиве разрешает пропустить (9) ...) и взять из него 3 элемента).

+0

Мне нравится этот подход, но он не достаточно быстрый для наших целей, извините. – abenci

0

Хотя это старая нить, добавление ответа Джозефа Стуртеванца может быть полезным. Его функция выйдет из строя, если первый столбец матрицы не равен нулю, но еще одно целое. Это, например, всегда в случае извлечения данных из Excel, как

object[,] objects = null; 
Excel.Range range = worksheet.get_Range("A1", "C5"); 
objects = range.Cells.Value; //columns start at 1, not at 0 

Функция GetRow может быть изменена следующим образом:

public static T[] GetRow<T>(T[,] matrix, int row, int firstColumn) 
    { 
     var columns = matrix.GetLength(1); 
     var array = new T[columns]; 
     for (int i = firstColumn; i < firstColumn + columns; ++i) 
      array[i-firstColumn] = matrix[row, i]; 
     return array; 
    } 
+0

Итак, 'firstColumn' - 0 для массивов на основе 0 и 1 для массивов на основе 1? – beppe9000

3

Почему бы не сделать общий метод расширения?

public static T[] GetRow<T>(this T[,] input2DArray, int row) where T : IComparable 
    { 
     var width = input2DArray.GetLength(0); 
     var height = input2DArray.GetLength(1); 

     if (row >= height) 
      throw new IndexOutOfRangeException("Row Index Out of Range"); 
     // Ensures the row requested is within the range of the 2-d array 


     var returnRow = new T[width]; 
     for(var i = 0; i < width; i++) 
      returnRow[i] = input2DArray[i, row]; 

     return returnRow; 
    } 

Как это все, что вам нужно код:

array2D = new double[,]; 
// ... fill array here 
var row = array2D.GetRow(4) // Implies getting 5th row of the 2-D Array 

Это полезно, если вы пытаетесь методов цепи после получения ряда и может быть полезным с LINQ команды, а также.

+1

У вас ширина и высота перепутаны. – Sebastian

+0

Правильно. Спасибо. –

+1

Редактированное и представленное в настоящее время представление этого решения не на 100% правильное. Вы должны учитывать область использования. Если вы берете двухмерный массив как, например, изображение, функция верна. Но если вы используете его как математическую матрицу, которая, я думаю, должна быть - размеры должны быть переключены. В матрице первым параметром является количество строк (псевдоним высоты), а второе - количество столбцов (псевдоним x). Поэтому имейте в виду область использования! Для математических функций вам нужно переключить положение параметра «i» и «width» в этом решении. –

Смежные вопросы