Tsukasa
Tsukasa

Reputation: 6562

Linq IEnumerable<IGrouping<string, Class>> back to List<Class>

How can I turn the following statement back to List<DocumentData>

IEnumerable<IGrouping<string, DocumentData>> documents = 
                 documentCollection.Select(d => d).GroupBy(g => g.FileName);

the goal is to get List that should be smaller than documentCollection. FileName contains duplicates so I want to make sure I don't have duplicate names.

I have also tried the following but it's still providing me with duplicate file names

documentCollection = 
    documentCollection.GroupBy(g => g.FileName).SelectMany(d => d).ToList();

Upvotes: 8

Views: 12182

Answers (2)

Douglas
Douglas

Reputation: 54927

Each IGrouping<string, DocumentData> is an IEnumerable<DocumentData>, so you could simply call SelectMany to flatten the sequences:

var list = documents.SelectMany(d => d).ToList();

Edit: Per the updated question, it seems like the OP wants to select just the first document for any given filename. This can be achieved by calling First() on each IGrouping<string, DocumentData> instance:

IEnumerable<DocumentData> documents = 
    documentCollection.GroupBy(g => g.FileName, StringComparer.OrdinalIgnoreCase)
                      .Select(g => g.First())
                      .ToList();

Upvotes: 15

MarcinJuraszek
MarcinJuraszek

Reputation: 125650

You haven't said what T should stand for in List<T> you're looking for, so here are couple the most likely to be desired:

  1. List<DocumentData> - rather pointless as you already have that on documentCollection

    var results = documents.SelectMany(g => g).ToList();
    
  2. List<KeyValuePair<string, List<DocumentData>>

    var results =
           documents.Select(g => new KeyValuePair(g.Key, g.ToList())).ToList();
    
  3. List<string> - just the names

    var results = documents.Select(g => g.Key).ToList();
    
  4. List<IGrouping<string, DocumentData>>

    var results = documents.ToList();
    

Upvotes: 4

Related Questions