2008-10-13 40 views
5

Làm cách nào tôi có thể làm phương pháp Ruby "Flatten" Ruby Method trong C#. Phương pháp này làm phẳng một mảng răng cưa thành mảng đơn chiều.Phương pháp Flatten Ruby trong C#

Ví dụ:

s = [ 1, 2, 3 ]   #=> [1, 2, 3] 
t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] 
a = [ s, t, 9, 10 ]  #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] 
a.flatten     #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 
+0

Bạn đang xử lý một mảng có răng cưa (mảng mảng) ở đây chứ không phải các mảng đa chiều. – leppie

+0

Chúc mừng, lỗi của tôi - đã được sắp xếp. – chrisntr

Trả lời

12

giải pháp đệ quy:

IEnumerable Flatten(IEnumerable array) 
{ 
    foreach(var item in array) 
    { 
     if(item is IEnumerable) 
     { 
      foreach(var subitem in Flatten((IEnumerable)item)) 
      { 
       yield return subitem; 
      } 
     } 
     else 
     { 
      yield return item; 
     } 
    } 
} 

EDIT 1:

Jon giải thích trong các ý kiến ​​tại sao nó không thể là một phương pháp chung chung, hãy xem!

CHỈNH SỬA 2:

Matt đề xuất đặt làm phương pháp mở rộng. Ở đây bạn đi, chỉ cần thay thế dòng đầu tiên với:

public static IEnumerable Flatten(this IEnumerable array) 

và bạn có thể sử dụng nó như thế này:

foreach(var item in myArray.Flatten()) { ... } 
+1

Suy nghĩ ban đầu của tôi là "Tại sao nó không chung chung?" - nhưng tất nhiên nó không thể vì chỉ hiếm khi là một phiên bản có thể lặp lại của T cũng là T. (ví dụ IEnumerable vẫn là một đối tượng, nhưng IEnumerable không phải là một chuỗi.) Nó có thể đáng làm rõ điều này trong câu trả lời. –

+0

Ngoài ra tôi không chắc chắn rằng có bất kỳ cách nào để khai báo một mảng rách rưới mạnh mẽ đánh máy trong C# là có? Nó phải là đối tượng [], có nghĩa là IEnumerable là một kiểu tham số hợp lý cho phương thức này. –

+0

Matt: Không chắc chắn những gì bạn có nghĩa là bởi "mảng rách rưới mạnh mẽ gõ" nhưng int [] [] và int [,] (cho mảng răng cưa và hình chữ nhật của ints tương ứng) là tốt. –

2

tôi sẽ trả lời trong một chú thích, nhưng tôi cần nhiều hơn 300 ký tự.

@ Giải pháp của Alexander là tuyệt vời, nhưng nó gặp sự cố với mảng chuỗi. Kể từ khi chuỗi thực hiện IEnumerable, tôi nghĩ rằng nó sẽ kết thúc trả về mỗi ký tự trong mỗi chuỗi. Bạn có thể sử dụng một tham số chung để nói với nó những loại điều bạn đang hy vọng đã trở lại trong những trường hợp này, ví dụ .:

public static IEnumerable Flatten<T>(IEnumerable e) 
{ 
    if (e == null) yield break; 
    foreach (var item in e) 
    { 
     if (item is T) 
      yield return (T)item; 
     else if (item is IEnumerable) 
     { 
      foreach (var subitem in Flatten<T>((IEnumerable)item)) 
       yield return subitem; 
     } 
     else 
      yield return item; 
    } 
} 
1

Không thể bạn chỉ cần sử dụng IEnumerable # SelectMany?