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

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow