HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Refactor foreach loops

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
foreachrefactorloops

Problem

I have 2 objects and I am comparing them to see which fields are equal and which are different.

But I am not sure my loop is 100% correct. Does this look ok? If so, what other ways could this be coded to make it 'neater'. e.g. using LINQ

I want to: loop through each DocumentType in both objects, and for each documentType - I want to loop through each DocumentTypeVersion and compare this.

foreach (DocumentType documentType in documentTypes)
{
    foreach (DocumentType importDocumentType in importedDocumentTypes)
    {

        if (documentType.Id == importDocumentType.Id)//ensure its the same documentType we are comparing
        {
            foreach (DocumentTypeVersion version in documentType.Versions)
            {
                foreach (DocumentTypeVersion importedVersion in importDocumentType.Versions)
                {
                    if (version.Id == importedVersion.Id)//ensure its the same documentTypeVersion we are comparing
                    {
                        //check if the versions are equal
                        bool areVersionsEqual = Equals(version, importedVersion);

                    }

                }
            }
        }
    }
}

Solution

An option would be to create two IEqualityComparers; one for DocumentType and one for DocumentTypeVersion. You could then easily call Intersect() and get the correct ones.

public class DocumentTypeIdComparer : IEqualityComparer
{
    public bool Equals(DocumentType docType1, DocumentType docType2)
    {
        return !(docType1 == null || docType2 == null) && docType1.Id == docType2.Id;           
    }
}

public class DocumentTypeVersionComparer : IEqualityComparer
{
    public bool Equals(DocumentTypeVersion docTypeVersion1, DocumentTypeVersion docTypeVersion2)
    {
        return !(docTypeVersion1 == null || docTypeVersion2 == null) && Object.Equals(docTypeVersion1, docTypeVersion2);           
    }
}


You will then be able to reduce your code to this;

var equalDocumentsById = documentTypes.Intersect(importDocumentTypes, new DocumentTypeIdComparer());
var equalVersions = documentTypes.Versions.Intersect(importDocumentTypes.Versions, new DocumentTypeVersionComparer());
var equalDocuments = equalDocumentsById.Where(doc => doc.Versions.Intersect(equalVersions, new DocumentTypeVersionComparer()).Any());


And then process equalDocuments as you please. If you want the documents which are not equal, simply switch .Count > 0 with .Count == 0.

Code Snippets

public class DocumentTypeIdComparer : IEqualityComparer<DocumentType>
{
    public bool Equals(DocumentType docType1, DocumentType docType2)
    {
        return !(docType1 == null || docType2 == null) && docType1.Id == docType2.Id;           
    }
}

public class DocumentTypeVersionComparer : IEqualityComparer<DocumentTypeVersion>
{
    public bool Equals(DocumentTypeVersion docTypeVersion1, DocumentTypeVersion docTypeVersion2)
    {
        return !(docTypeVersion1 == null || docTypeVersion2 == null) && Object.Equals(docTypeVersion1, docTypeVersion2);           
    }
}
var equalDocumentsById = documentTypes.Intersect(importDocumentTypes, new DocumentTypeIdComparer());
var equalVersions = documentTypes.Versions.Intersect(importDocumentTypes.Versions, new DocumentTypeVersionComparer());
var equalDocuments = equalDocumentsById.Where(doc => doc.Versions.Intersect(equalVersions, new DocumentTypeVersionComparer()).Any());

Context

StackExchange Code Review Q#73943, answer score: 13

Revisions (0)

No revisions yet.