Find struct elements with same ID but different other field values, from 2 struct arrays

Viewed 17

Code is similar to below:

    type Contact struct {
    Id    string
    Email string
}

type EmailDifference struct {
    Id       string
    OldEmail string
    NewEmail string
}

func main() {
    ContactList1 := []Contact{
        Contact{
            Id:    "A01",
            Email: "email1@mail.com",
        },
        Contact{
            Id:    "A02",
            Email: "secondemail@mail.com",
        },
        Contact{
            Id:    "C00",
            Email: "someemail@mail.com",
        },
    }

    ContactList2 := []Contact{
        Contact{
            Id:    "A01",
            Email: "email23441@mail.com",
        },
        Contact{
            Id:    "A02",
            Email: "2ndmail@mail.com",
        },
        Contact{
            Id:    "C00",
            Email: "someemail@mail.com",
        },
    }

    //How to find contacts with same ID but different emails from the above 2 contact lists?
}

I need to output a slice []EmailDifference{} containing contacts with same ID but different emails. How to do it efficiently, without using 2 for loops (i.e. comparing each element of ContactList1 with all elements of ContactList2 until a match in ID is found, then note that result if 2 emails are different)?

1 Answers

If you want to avoid the two nested loops, you could use a map. Still requires two loops, but not nested. Whether this is more efficient than the nested loops, probably depends on the size of both lists.

package main

import "fmt"

type Contact struct {
    Id    string
    Email string
}

type EmailDifference struct {
    Id       string
    OldEmail string
    NewEmail string
}

func main() {
    ContactList1 := []Contact{
        Contact{
            Id:    "A01",
            Email: "email1@mail.com",
        },
        Contact{
            Id:    "A02",
            Email: "secondemail@mail.com",
        },
        Contact{
            Id:    "C00",
            Email: "someemail@mail.com",
        },
    }

    ContactList2 := []Contact{
        Contact{
            Id:    "A01",
            Email: "email23441@mail.com",
        },
        Contact{
            Id:    "A02",
            Email: "2ndmail@mail.com",
        },
        Contact{
            Id:    "C00",
            Email: "someemail@mail.com",
        },
    }

    //How to find contacts with same ID but different emails from the above 2 contact lists?

    var diffs []EmailDifference

    // Convert ContactList2 to map
    ContactEmailMap2 := make(map[string]string, len(ContactList2))
    for _, c := range ContactList2 {
        ContactEmailMap2[c.Id] = c.Email
    }

    // Loop through ContactList1
    for _, c1 := range ContactList1 {
        c2email, isPresent := ContactEmailMap2[c1.Id]
        if isPresent && c1.Email != c2email {
            diffs = append(diffs, EmailDifference{Id: c1.Id, OldEmail: c1.Email, NewEmail: c2email})
        }
    }

    fmt.Printf("%+v", diffs)
}
Related