2010-02-10 160 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));