Creating Two Similar Functions

I have two functions in Go that do almost the same thing. They take a fragment of structures that has an ID field and re-sort it into a map indexed by that field. Then they attach it to a field of another structure, which is also identified by an identifier.

Two functions do the same, but add to two different fields in the structure. I want the methods to be universal, but I'm not sure how to do this. I would expect this to be possible with a pointer, but I'm not sure how to do this.

Function 1:

func addPremiereDatesToMovies(m []Movie, pd []PremiereDate) ([]Movie, error) {
    pds := make(map[int64][]PremiereDate)

    // Key-index the premiere-date array for easier lookup
    for _, value := range pd {
        pds[value.Id] = append(pds[value.Id], value)
    }

    // Append premiere dates to movies where such exist
    for key, value := range m {
        if _, ok := pds[value.Id]; !ok {  // <-- How to make this generic?
            m[key].PremiereDates = []PremiereDate{}
            continue
        }

        m[key].PremiereDates = pds[value.Id]
    }

    return m, nil
}

Function 2:

func addGenresToMovies(m []Movie, g []Genre) ([]Movie, error) {
    gs := make(map[int64][]Genre)

    // Key-index the genre array for easier lookup
    for _, value := range g {
        gs[value.Id] = append(gs[value.Id], value)
    }

    // Append genres to movies where such exist
    for key, value := range m {
        if _, ok := gs[value.Id]; !ok { // <-- How to make this generic?
            m[key].Genres = []Genre{}
            continue
        }

        m[key].Genres = gs[value.Id]
    }

    return m, nil
}

They seem to look very similar. I can do this, but I cannot figure out how to generally describe the "value.Id" field on line 11.

Thank.

+4
1

kostya, , , 20 - cast, revenues_per_country .. 20 .

, case , .

, :

: movies = addStuffToMovies(movies, genres)

// addStuffToMovies adds fields to a movie where the ID matches
func addStuffToMovies(movies []Movie, stuff interface{}) []Movie {

    // Go through the movies list
    for current, movie := range movies {

        // check the type and append based on that
        switch v := stuff.(type) {

        // This is the section you'll need to duplicate for each type of field
        case []Genre:
            for _, item := range v {
                // if it matches, append it to Genres
                if item.Id == movie.Id {
                    movies[current].Genres = append(movies[current].Genres, item)
                }
            }

        // This is the section you'll need to duplicate for each type of field
        case []PremiereDate:
            for _, item := range v {
                // if it matches, append it to PremiereDates
                if item.Id == movie.Id {
                    movies[current].PremiereDates = append(movies[current].PremiereDates, item)
                }
            }
        }
    }
    return movies
}

, , interface, stuff interface{} - []FieldInterface GetID(), GetType() case. , -, . , , switch, , .

+3

All Articles