2008-10-13 51 views
5

如何在C#中執行Ruby方法"Flatten" Ruby Method。此方法將鋸齒狀陣列變平成一維陣列。在C#中拼合Ruby方法#

例如:

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

您正在處理鋸齒(數組數組)陣列,而不是多維數組。 – leppie 2008-10-13 09:21:43

+0

乾杯,我的錯誤 - 排序。 – chrisntr 2008-10-13 09:27:47

回答

12

遞歸解決方案:

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; 
     } 
    } 
} 

編輯1:

Jon解釋了爲什麼評論它不可能是一個通用的方法,一起來看看!

編輯2:

Matt建議使得它的擴展方法。在這裏,你走了,只需更換的第一行:

public static IEnumerable Flatten(this IEnumerable array) 

,你可以使用它像這樣:

foreach(var item in myArray.Flatten()) { ... } 
2

我會在評論已作出迴應,但我需要超過300個字符。

@亞歷山大的解決方案很棒,但它遇到了字符串數組的問題。由於字符串實現IEnumerable,我認爲它將最終返回每個字符串中的每個字符。您可以使用泛型參數來告訴它你希望在這些情況下又回到什麼樣的事情,例如:

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

你不能只使用IEnumerable的#的SelectMany?