2011-01-26 45 views
25

Tôi đang cố gắng tìm ra cách lấy một chiều từ một mảng đa chiều (vì lợi ích của đối số, giả sử là 2D), tôi có một mảng đa chiều :Cách lấy kích thước (slice) từ mảng đa chiều

double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } }; 

Nếu đó là một mảng lởm chởm, tôi sẽ chỉ cần gọi d[0] và đó sẽ cho tôi một loạt các {1, 2, 3, 4, 5}, là có cách nào tôi có thể đạt được cùng với một mảng 2D?

+1

Có vẻ như bạn muốn tạo một mảng tham chiếu đến một lát mảng. Tôi không nghĩ điều đó là có thể. – Gabe

+0

@Gabe, yah, tôi đã xem qua tài liệu và tôi không thể thấy bất kỳ thứ gì có thể giúp tôi lấy một lát, vì vậy tôi quyết định xác nhận với cộng đồng. Cảm ơn bạn về thông tin! :) – Kiril

+2

Tôi chỉ nhận thấy rằng câu hỏi của tôi là một bản sao: http://stackoverflow.com/questions/1406083/array-slice-in-c – Kiril

Trả lời

17

Không. Tất nhiên bạn có thể viết một lớp bao bọc đại diện cho một lát, và có một trình chỉ mục nội bộ - nhưng không có gì sẵn có. Cách tiếp cận khác sẽ là viết một phương thức tạo ra một bản sao của một lát và đưa lại một véc tơ - nó phụ thuộc vào việc bạn muốn có một bản sao hay không.

using System; 
static class ArraySliceExt 
{ 
    public static ArraySlice2D<T> Slice<T>(this T[,] arr, int firstDimension) 
    { 
     return new ArraySlice2D<T>(arr, firstDimension); 
    } 
} 
class ArraySlice2D<T> 
{ 
    private readonly T[,] arr; 
    private readonly int firstDimension; 
    private readonly int length; 
    public int Length { get { return length; } } 
    public ArraySlice2D(T[,] arr, int firstDimension) 
    { 
     this.arr = arr; 
     this.firstDimension = firstDimension; 
     this.length = arr.GetUpperBound(1) + 1; 
    } 
    public T this[int index] 
    { 
     get { return arr[firstDimension, index]; } 
     set { arr[firstDimension, index] = value; } 
    } 
} 
public static class Program 
{ 
    static void Main() 
    { 
     double[,] d = new double[,] { { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 } }; 
     var slice = d.Slice(0); 
     for (int i = 0; i < slice.Length; i++) 
     { 
      Console.WriteLine(slice[i]); 
     } 
    } 
} 
+0

cảm ơn cho thông tin ... sau khi không tìm thấy bất cứ điều gì sẵn có, tôi giả định rằng tôi ' d phải viết một wrapper, nhưng tôi muốn chắc chắn rằng tôi đã không bỏ lỡ bất cứ điều gì. Cảm ơn một lần nữa! – Kiril

+0

@Lirik xem bản cập nhật cho mẫu –

+0

_ (Bạn hiểu rồi, đừng bao giờ để ý đến bình luận bên phải) _ - Làm tốt, +1 –

3

Mảng hình chữ nhật không được xây dựng cho mục đích này. Nếu bạn cần loại chức năng đó, bạn nên chuyển sang mảng bị lởm chởm. Nó là khá đơn giản để viết một chức năng mà sẽ chuyển đổi một mảng hình chữ nhật thành một lởm chởm.

Bạn cũng có thể xây dựng lại mảng đó bằng cách gọi GetLength (tham số int) trên thứ nguyên thích hợp và sau đó lập chỉ mục nó đúng cách để lấy từng giá trị. Nó sẽ rẻ hơn so với chuyển đổi toàn bộ mảng, nhưng tùy chọn rẻ nhất là thay đổi nó để sử dụng các mảng bị lởm chởm.

+0

bạn viết "Nó khá đơn giản để viết một chức năng mà sẽ chuyển đổi một mảng hình chữ nhật thành một lởm chởm." <--- nhưng có lẽ khá kém hiệu quả nếu một mảng lớn, bởi vì bạn phải quét toàn bộ mảng? làm thế nào để bạn chuyển đổi hình chữ nhật để lởm chởm mà không cần xây dựng lại nó? – barlop

4

Phiên bản cải tiến của that answer:

public static IEnumerable<T> SliceRow<T>(this T[,] array, int row) 
{ 
    for (var i = array.GetLowerBound(1); i <= array.GetUpperBound(1); i++) 
    { 
     yield return array[row, i]; 
    } 
} 

public static IEnumerable<T> SliceColumn<T>(this T[,] array, int column) 
{ 
    for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++) 
    { 
     yield return array[i, column]; 
    } 
} 
+0

Chính xác những gì tôi cần. IEnumerable. – realPT

Các vấn đề liên quan