Home > Back-end >  Golang - How to iterate through two slices at the same time
Golang - How to iterate through two slices at the same time

Time:02-02

I'm trying to write a function that takes in a struct, and within that there are two nested structs. I need to iterate through both nested structs, find the "Service" field and remove the prefixes that are separated by the '-'.

I've written a function that does what I want it to and removes the prefixes, however it consists of two for loops that loop through the two separate structs. Is their a way for me to write this function in a way that it loops through the structs in one for loop?

Here are the structs:

var myJson = `
{
    "ID": "hgfd5432",
    "Greeting": "Welcome!",
    "ServiceNames": [
        {
          "Service": "sevice-name-service1",
          "Version": "1.8"
        },
        {
          "Service": "sevice-name-service2",
          "Version": "1.8"
        },
        {
          "Service": "sevice-name-service3",
          "Version": "1.9"
        },
        {
          "Service": "sevice-name-service4",
          "Version": "0.6"
        }
      ],
      "Services": [
        {
          "Service": "sevice-name-service5",
          "Version": "1.8"
        }
        ],
    "BusinessUnit": "Unit 1",
    "Queue": "UK73_Advocacy_PCCT",
    "Input": "Default",
  }`

type Profile struct {
ProfileId     string        `json:"ID"`
Input         string        `json:"Input"`
ParentProfile string        `json:"ParentProfile"`
Persona       string        `json:"Persona"`
BusinessUnit  string        `json:"BusinessUnit"`
Greeting      string        `json:"Greeting"`
Queue         string        `json:"Queue"`
ServiceNames  []ServiceKey  `json:"ServiceNames"`
Services      []ServiceInfo `json:"Services"`

And here is the function:

func removePrefix(inputParameters *Profile) error {

for i := 0; i < len(inputParameters.ServiceNames); i   {
    a := strings.Split(inputParameters.ServiceNames[i].Service, "-")
    s := a[len(a)-1]
    inputParameters.ServiceNames[i].Service = s
}

for i := 0; i < len(inputParameters.Services); i   {
    a := strings.Split(inputParameters.Services[i].Service, "-")
    s := a[len(a)-1]
    inputParameters.Services[i].Service = s
}
return nil

CodePudding user response:

One way you can do this is,

serviceNamesLength := len(inputParameters.ServiceNames)
servicesLength := len(inputParameters.Services)

maxLength := serviceNamesLength
if servicesLength > maxLength {
    maxLength = servicesLength
}

for i := 0; i < maxLength; i   {
    if i < servicesLength {
        // services stuff
    }
    if i < serviceNamesLength {
        // services names stuff
    }
}

CodePudding user response:

here's how you can do this,by using concurrency:

func ConcurrencyLoop(inputParameters *Profile) {

    done := make(chan interface{})
    var wg sync.WaitGroup
    wg.Add(2)

    servicesNameChan := TransformServiceNames(done, inputParameters.ServiceNames, &wg)
    servicesInfoChan := TransformServiceInfo(done, inputParameters.Services, &wg)

    if servicesName, ok := <-servicesNameChan; ok {
        inputParameters.ServiceNames = servicesName
    }
    if servicesInfo, ok := <-servicesInfoChan; ok {
        inputParameters.Services = servicesInfo
    }


    close(done)
    wg.Wait()

}

func TransformServiceNames(done <-chan interface{}, servicesKey []ServiceKey, wg *sync.WaitGroup) <-chan []ServiceKey {
    keysChan := make(chan []ServiceKey)
    go func() {
        defer wg.Done()
        transformedServicekeys := make([]ServiceKey, 0)
        for _, serviceKey := range servicesKey {
            a := strings.Split(serviceKey.Service, "-")
            s := a[len(a)-1]
            transformedServicekeys = append(transformedServicekeys, ServiceKey{
                Service: s,
            })
        }
        for {
            select {
            case <-done:
                return
            case keysChan <- transformedServicekeys:
            }
        }
    }()
    return keysChan
}

func TransformServiceInfo(done <-chan interface{}, servicesKey []ServiceInfo, wg *sync.WaitGroup) <-chan []ServiceInfo {
    keysChan := make(chan []ServiceInfo)
    go func() {
        defer wg.Done()
        transformedServiceinfo := make([]ServiceInfo, 0)
        for _, serviceKey := range servicesKey {
            a := strings.Split(serviceKey.Service, "-")
            s := a[len(a)-1]
            transformedServiceinfo = append(transformedServiceinfo, ServiceInfo{
                Service: s,
            })
        }
        for {
            select {
            case <-done:
                return
            case keysChan <- transformedServiceinfo:
            }
        }
    }()
    return keysChan
}

  • Related