2010-02-10 229 views
5

我有一個要轉換爲單維集合的IEnumerable<IEnumerable<T>>集合。用通用的擴展方法可以實現嗎?現在我正在做這個來實現它。如何將IEnumerable <IEnumerable <T>>轉換爲IEnumerable <T>

List<string> filteredCombinations = new List<string>(); 

//For each collection in the combinated results collection 
foreach (var combinatedValues in combinatedResults) 
{ 
    List<string> subCombinations = new List<string>(); 
    //For each value in the combination collection 
    foreach (var value in combinatedValues) 
    { 

     if (value > 0) 
     { 
      subCombinations.Add(value.ToString()); 
     } 
    } 
    if (subCombinations.Count > 0) 
    { 
     filteredCombinations.Add(String.Join(",",subCombinations.ToArray())); 
    } 
} 

如果無法獲得一個通用的解決方案,我該如何以優雅的方式對其進行優化。

+1

在標題的問題是在這裏找到答案:HTTP://計算器。 com/questions/1590723/flatten-list-in-linq – 2010-02-10 22:34:47

回答

3

在這裏你去:

var strings = combinedResults.Select 
    (
     c => c.Where(i => i > 0) 
     .Select(i => i.ToString()) 
    ).Where(s => s.Any()) 
    .Select(s => String.Join(",", s.ToArray()); 
+0

但是原始代碼產生一個字符串列表,而不是一個字符串... – 2010-02-10 21:59:07

+0

D'oh。糾正。 – 2010-02-10 22:02:31

+1

這整個問題一直很奇怪!措辭問了一個問題,這個例子問另一個問題。你已經完全回答了第三個不同的問題,並且被接受了......我已經發布了正確答案,並且沒有投票(不是我介意的,這只是有趣的)。 – 2010-02-10 22:05:34

18

對此,您可以使用Enumerable.SelectMany擴展方法。

如果我看了你的代碼正確,該代碼將是:

var filteredCombinations = combinatedResults.SelectMany(o => o) 
    .Where(value => value > 0) 
    .Select(v => v.ToString()); 

編輯:作爲評價說,上面的代碼是不是子集的每一個元素加入到一個字符串,如原代碼呢。使用內置的方法,你可以做到這一點使用:

var filteredCombinations = combinatedResults 
    .Where(resultSet => resultSet.Any(value => value > 0) 
    .Select(resultSet => String.Join(",", 
     resultSet.Where(value => value > 0) 
        .Select(v => v.ToString()).ToArray())); 
+0

打我吧... – 2010-02-10 21:11:28

+0

如果你想讓每個子集成爲新集合的一個元素,該怎麼辦?這就是我對String.Join所做的... – 2010-02-10 21:30:55

+0

這是不對的 - 它忽略了「加入」要求。 – 2010-02-10 21:53:07

3

我會親自使用Enumerable.SelectMany,爲suggested by driis

但是,如果你想這個自己實現,這將是更清潔的事:

IEnumerable<T> MakeSingleEnumerable<T>(IEnumerable<IEnumerable<T>> combinatedResults) 
{ 
    foreach (var combinatedValues in combinatedResults) { 
     foreach (var value in combinatedValues) 
       yield return value; 
    } 
} 
+0

是* SelectMany *更好,但似乎很多人不知道「收益率回報」 - 正如這個問題所證明的那樣。 – 2010-02-10 21:49:12

2

你問了兩個不同的問題。你在標題中描述的那個已經被drilis回答了。

但您的示例代碼是一個不同的問題。我們可以分階段重構它。第1步,建立使用一些的LINQ的subCombinations列表:

List<string> filteredCombinations = new List<string>(); 

//For each collection in the combinated results collection 
foreach (var combinatedValues in combinatedResults) 
{ 
    var subCombinations = combinatedValues.Where(v => v > 0) 
              .Select(v => v.ToString()) 
              .ToList(); 

    if (subCombinations.Count > 0) 
     filteredCombinations.Add(string.Join(",",subCombinations.ToArray())); 
} 

現在外環,留給我們只是這樣的:

var filteredCombinations = combinatedResults 
    .Select(values => values.Where(v => v > 0) 
          .Select(v => v.ToString()) 
          .ToArray()) 
    .Where(a => a.Count > 0) 
    .Select(a => string.Join(",", a)); 
相關問題