1

basically I have this:

package main

import "fmt"

type Struct1 struct {
    id   int
    name string
}

type Struct2 struct {
    id       int
    lastname string
}

type Struct3 struct {
    id   int
    real bool
}

func main() {
    var (
     s1 []Struct1
     s2 []Struct2
     s3 []Struct3
    )
    s1 = append(s1, Struct1{id: 1, name: "Eliot"}, Struct1{id: 2, name: "Tyrell"}, Struct1{id: 3, name: "Mr Robot"})
    s2 = append(s2, Struct2{id: 1, lastname: "Anderson"}, Struct2{id: 2, lastname: "Wellick"})
    s3 = append(s3, Struct3{id: 1, real: true}, Struct3{id: 2, real: true}, Struct3{id: 3, real: false})
}

I want to show something like this:

  • Eliot Anderson real(true)
  • Tyrell Wellick real(true)

But I don't want to loop the s1 inside the s2 and then inside the s3

Example:

for i := 0; i < len(s1); i++ {
        for j := 0; j < len(s2); j++ {
            if s1[i].id == s2[j].id {
                for k := 0; k < len(s3); k++ {
                    if s2[j].id == s3[k].id {
                        // some code ...
                    }
                }
            }
        }
    }

So, what other ways are there to doing that?

1
  • Parallel arrays are usually a sign that you did something wrong in the design phase. Commented Dec 7, 2017 at 3:53

3 Answers 3

3

The right way would be to put them in a hash(called map in Golang). That way you can get performance and you could do with only one loop iterating over id's.

Here's an example with your sample data:

package main

import (
    "fmt"
)

type Struct1 struct {
    id   int
    name string
}

type Struct2 struct {
    id       int
    lastname string
}

type Struct3 struct {
    id   int
    real bool
}

func main() {
    //var (
    //s1 []Struct1
    //      s2 []Struct2
    //  s3 []Struct3
    //  )
    s1Hash := make(map[int]Struct1)
    s2Hash := make(map[int]Struct2)
    s3Hash := make(map[int]Struct3)

    s11 := Struct1{id: 1, name: "Eliot"}
    s12 := Struct1{id: 2, name: "Tyrell"}
    s13 := Struct1{id: 3, name: "Mr Robot"}
    s1Hash[s11.id] = s11
    s1Hash[s12.id] = s12
    s1Hash[s13.id] = s13

    s21 := Struct2{id: 1, lastname: "Anderson"}
    s22 := Struct2{id: 2, lastname: "Wellick"}
    s2Hash[s21.id] = s21
    s2Hash[s22.id] = s22

    s31 := Struct3{id: 1, real: true}
    s32 := Struct3{id: 2, real: true}
    s33 := Struct3{id: 3, real: false}
    s3Hash[s31.id] = s31
    s3Hash[s32.id] = s32
    s3Hash[s33.id] = s33

    //s1 = append(s1, Struct1{id: 1, name: "Eliot"}, Struct1{id: 2, name: "Tyrell"}, Struct1{id: 3, name: "Mr Robot"})
    //s2 = append(s2, Struct2{id: 1, lastname: "Anderson"}, Struct2{id: 2, lastname: "Wellick"})
    //s3 = append(s3, Struct3{id: 1, real: true}, Struct3{id: 2, real: true}, Struct3{id: 3, real: false})

    //i to loop over possible id range
    for i := 1; i <= len(s1Hash); i++ {
        fmt.Println("i is ", i)
        if _, ok := s1Hash[i]; ok {
            fmt.Printf("Name: %s ", s1Hash[i].name)
        }

        if _, ok := s2Hash[i]; ok {
            fmt.Printf(" Lastname: %s ", s2Hash[i].lastname)
        }

        if _, ok := s3Hash[i]; ok {
            fmt.Printf(" Real: %t\n", s3Hash[i].real)
        }
        //fmt.Printf("%s %s real:%t\n", s1Hash[i].name, s2[i].lastname, s3[i].real)
    }

}

Output:

i is  1
Name: Eliot  Lastname: Anderson  Real: true
i is  2
Name: Tyrell  Lastname: Wellick  Real: true
i is  3
Name: Mr Robot  Real: false

Check this out on playground. Hope this helps!

p.s. : Eventually if you may delete all struct entries for some ID's and add newer ID's - you can consider adding the valid ID's into a map map[int]bool (mymap[id] = true) and iterate over the map using range instead of the for i.. as above.

Sign up to request clarification or add additional context in comments.

1 Comment

Your right, I must use a map instead array, eventually, it's better to manage a lot of information, besides I like this way of solution, thanks a lot :)
0

Use a map for indexing the data by the person name.

type Person struct {
     firstName: string
     lastName: string 
     real: string
}

var data map[int]Person

Then look up and put data to the map.

Comments

0

In fact to join all first elements, then all second etc, you don’t need to make a cycle in a cycle:

Prepare every slice as a map:

m1 := make(map[int]string)
for i:=0; i < len(s1); i ++ {
    m1[s1[i].id] = s1[i].Name
}

The same for 2 other slices. Finally iterate once:

for i:=0; i < len(s1); i ++ {
    fmt.Println(m1[i], m2[i], m3[i])
}

This solution supposes all slices have corresponding items. If not, you should decide what to do with an element without its fragment: ignore, replace blank with some placeholders, break whole cycle etc. For example, you decided firstName is mandatory (we will iterate by it), secondName is optional and should be replaced with ? in case of absence, and real is absolutely obligatory for the whole cycle - if it's absent we break further work and return empty slice:

type Person struct { // corrected struct from the neighbour recipe
     firstName: string
     lastName: string 
     real: bool
}

var persons []Person // slice for result

for i, firstName := range m1 { // iterate by keys and values of m1
    secondName, ok := m2[i]
    if !ok {
       secondName = "?"
    }
    real, ok := m3[i]
    if !ok {
       persons = []Person
       break
    }
    person := Person{firstName, secondName, real}
    persons = append(persons, person)
}

5 Comments

The result is panic: runtime error: index out of range. play.golang.org/p/DsYlYIT426
That's because the s1 and s3 doesn't have the same length
@peterSO, quite right - because slices have different length, and you have to decide what to do in this case.
@juancsr I've updated the recipe, how to deal with maps and absent values
@EugeneLisitsky yeah, I realize that it's better to make a map with the structs, thank you for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.