Leandro Tavares
Leandro Tavares

Reputation: 400

Distinct values from a nested list using lambda

I have a list of Documents which contains a list of DocumentGroups, and I want to select all the distinct DocumentGroups to perform an operation. Iterating through 2 loops is trivial, but I was not able to find out how to do that with lambda expressions. Could anyone provide some help?

Those are the classes

public class Document
{
     public int DocumentID {get; set;}

     public string DocumentName {get; set;}

     public List<DocumentGroup> DocumentGroups { get; set; }
}

public class DocumentGroup : IEquatable<DocumentGroup>
{
    public int DocumentGroupID { get; set; }

    public string GroupName { get; set; }

    public bool Equals(DocumentGroup other)
    {
        if (other == null)
            return false;

        return other.DocumentGroupID == this.DocumentGroupID;
    }
}

That is the trivial code

List<DocumentGroup> distinctDocumentGroups = new List<DocumentGroup>();

foreach (Document d in documentList)
{
     foreach(DocumentGroup dg in d.DocumentGroups)
     { 
         if (!distinctDocumentGroups.Contains(dg))
             distinctDocumentGroups.Add(dg);
     }
}

Thanks, Leandro Tavares

Upvotes: 3

Views: 1809

Answers (1)

Jon Skeet
Jon Skeet

Reputation: 1499790

I suspect you just want a combination of [SelectMany]1 (to flatten the document list to a document group sequence) and then Distinct to get the distinct elements:

var documentGroups = documentList.SelectMany(d => d.DocumentGroups)
                                 .Distinct()
                                 .ToList();

You'll need to override GetHashCode in DocumentGroup as well, as noted by Servy. In this case that's trivial:

public override int GetHashCode()
{
    return DocumentGroupId;
}

Also note that having DocumentGroupId mutable while being the key for equality is worrying. If you can, change it to be immutable and pass the ID into the constructor.

Upvotes: 3

Related Questions