2010-02-10 50 views
5

Tôi có một bộ sưu tập IEnumerable<IEnumerable<T>> mà tôi muốn chuyển đổi thành một bộ sưu tập thứ nguyên duy nhất. Có thể đạt được điều này với một phương pháp mở rộng chung không? Ngay bây giờ tôi đang làm điều này để đạt được nó.Làm thế nào để chuyển đổi một IEnumerable <IEnumerable <T>> thành 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())); 
    } 
} 

Nếu không thể có giải pháp chung, làm cách nào để tối ưu hóa điều này một cách thanh lịch.

+1

các câu hỏi trong tiêu đề được trả lời ở đây: http: // stackoverflow. com/questions/1590723/flatten-list-in-linq –

Trả lời

3

Ở đây bạn đi:

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

Nhưng mã gốc tạo ra một danh sách các chuỗi, không phải một chuỗi ... –

+0

D'oh. Sửa chữa. –

+1

Toàn bộ câu hỏi này là kỳ quái! Từ ngữ hỏi một câu hỏi, ví dụ này hỏi một câu hỏi khác. Và bạn đã trả lời một câu hỏi thứ ba, hoàn toàn khác nhau, và đã được chấp nhận ... Tôi đã đăng câu trả lời đúng, và không có phiếu bầu (không phải là tôi nhớ, nó chỉ là thú vị.) –

18

Bạn có thể sử dụng phương thức mở rộng Enumerable.SelectMany cho việc này.

Nếu tôi đọc mã của bạn một cách chính xác, mã cho rằng sẽ là:

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

Sửa: Theo nhận xét, các mã trên không được tham gia mỗi phần tử của tập con thành một chuỗi, như bản gốc mã. Sử dụng các phương pháp tích hợp, bạn có thể làm điều đó bằng:

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

đánh bại tôi ... –

+0

Điều gì sẽ xảy ra nếu bạn muốn mọi tập hợp con trở thành một phần tử của bộ sưu tập mới? Đó là những gì tôi làm với String.Join ... –

+0

Điều này không đúng - nó bỏ qua yêu cầu 'Tham gia'. –

3

Cá nhân tôi sẽ sử dụng Enumerable.SelectMany, như suggested by driis.

Tuy nhiên, nếu bạn muốn thực hiện điều này cho mình, nó sẽ sạch hơn nhiều việc phải làm:

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

có * SelectMany * là tốt hơn, nhưng có vẻ như rất nhiều người không biết về "lợi tức lợi nhuận" - được chứng minh bằng câu hỏi này. –

2

Bạn hỏi hai câu hỏi khác nhau. Một trong những bạn mô tả trong tiêu đề đã được trả lời bởi drilis.

Nhưng mã ví dụ của bạn là một vấn đề khác. Chúng ta có thể cấu trúc lại nó theo từng giai đoạn. Bước 1, xây dựng danh sách subCombinations sử dụng một số LINQ:

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

Bây giờ các vòng ngoài, để lại cho chúng ta chỉ này:

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)); 
Các vấn đề liên quan