Golang – 如何同时遍历两个切片

huangapple go评论109阅读模式
英文:

Golang - How to iterate through two slices at the same time

问题

我正在尝试编写一个函数,该函数接受一个结构体作为参数,其中包含两个嵌套的结构体。我需要遍历这两个嵌套的结构体,找到"Service"字段,并删除由"-"分隔的前缀。

我已经编写了一个函数,它可以实现我想要的功能并删除前缀,但是它由两个for循环组成,分别遍历这两个独立的结构体。有没有办法让我以一种方式编写这个函数,使它可以在一个for循环中遍历这两个结构体?

以下是结构体的定义:

  1. var myJson = `
  2. {
  3. "ID": "hgfd5432",
  4. "Greeting": "Welcome!",
  5. "ServiceNames": [
  6. {
  7. "Service": "sevice-name-service1",
  8. "Version": "1.8"
  9. },
  10. {
  11. "Service": "sevice-name-service2",
  12. "Version": "1.8"
  13. },
  14. {
  15. "Service": "sevice-name-service3",
  16. "Version": "1.9"
  17. },
  18. {
  19. "Service": "sevice-name-service4",
  20. "Version": "0.6"
  21. }
  22. ],
  23. "Services": [
  24. {
  25. "Service": "sevice-name-service5",
  26. "Version": "1.8"
  27. }
  28. ],
  29. "BusinessUnit": "Unit 1",
  30. "Queue": "UK73_Advocacy_PCCT",
  31. "Input": "Default",
  32. }`
  33. type Profile struct {
  34. ProfileId string `json:"ID"`
  35. Input string `json:"Input"`
  36. ParentProfile string `json:"ParentProfile"`
  37. Persona string `json:"Persona"`
  38. BusinessUnit string `json:"BusinessUnit"`
  39. Greeting string `json:"Greeting"`
  40. Queue string `json:"Queue"`
  41. ServiceNames []ServiceKey `json:"ServiceNames"`
  42. Services []ServiceInfo `json:"Services"`
  43. }

以下是该函数的代码:

  1. func removePrefix(inputParameters *Profile) error {
  2. for i := 0; i < len(inputParameters.ServiceNames); i++ {
  3. a := strings.Split(inputParameters.ServiceNames[i].Service, "-")
  4. s := a[len(a)-1]
  5. inputParameters.ServiceNames[i].Service = s
  6. }
  7. for i := 0; i < len(inputParameters.Services); i++ {
  8. a := strings.Split(inputParameters.Services[i].Service, "-")
  9. s := a[len(a)-1]
  10. inputParameters.Services[i].Service = s
  11. }
  12. return nil
  13. }

希望对你有所帮助!

英文:

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:

  1. var myJson = `
  2. {
  3. &quot;ID&quot;: &quot;hgfd5432&quot;,
  4. &quot;Greeting&quot;: &quot;Welcome!&quot;,
  5. &quot;ServiceNames&quot;: [
  6. {
  7. &quot;Service&quot;: &quot;sevice-name-service1&quot;,
  8. &quot;Version&quot;: &quot;1.8&quot;
  9. },
  10. {
  11. &quot;Service&quot;: &quot;sevice-name-service2&quot;,
  12. &quot;Version&quot;: &quot;1.8&quot;
  13. },
  14. {
  15. &quot;Service&quot;: &quot;sevice-name-service3&quot;,
  16. &quot;Version&quot;: &quot;1.9&quot;
  17. },
  18. {
  19. &quot;Service&quot;: &quot;sevice-name-service4&quot;,
  20. &quot;Version&quot;: &quot;0.6&quot;
  21. }
  22. ],
  23. &quot;Services&quot;: [
  24. {
  25. &quot;Service&quot;: &quot;sevice-name-service5&quot;,
  26. &quot;Version&quot;: &quot;1.8&quot;
  27. }
  28. ],
  29. &quot;BusinessUnit&quot;: &quot;Unit 1&quot;,
  30. &quot;Queue&quot;: &quot;UK73_Advocacy_PCCT&quot;,
  31. &quot;Input&quot;: &quot;Default&quot;,
  32. }`
  33. type Profile struct {
  34. ProfileId string `json:&quot;ID&quot;`
  35. Input string `json:&quot;Input&quot;`
  36. ParentProfile string `json:&quot;ParentProfile&quot;`
  37. Persona string `json:&quot;Persona&quot;`
  38. BusinessUnit string `json:&quot;BusinessUnit&quot;`
  39. Greeting string `json:&quot;Greeting&quot;`
  40. Queue string `json:&quot;Queue&quot;`
  41. ServiceNames []ServiceKey `json:&quot;ServiceNames&quot;`
  42. Services []ServiceInfo `json:&quot;Services&quot;`

And here is the function:

  1. func removePrefix(inputParameters *Profile) error {
  2. for i := 0; i &lt; len(inputParameters.ServiceNames); i++ {
  3. a := strings.Split(inputParameters.ServiceNames[i].Service, &quot;-&quot;)
  4. s := a[len(a)-1]
  5. inputParameters.ServiceNames[i].Service = s
  6. }
  7. for i := 0; i &lt; len(inputParameters.Services); i++ {
  8. a := strings.Split(inputParameters.Services[i].Service, &quot;-&quot;)
  9. s := a[len(a)-1]
  10. inputParameters.Services[i].Service = s
  11. }
  12. return nil

答案1

得分: 1

你可以这样做:

  1. serviceNamesLength := len(inputParameters.ServiceNames)
  2. servicesLength := len(inputParameters.Services)
  3. maxLength := serviceNamesLength
  4. if servicesLength > maxLength {
  5. maxLength = servicesLength
  6. }
  7. for i := 0; i < maxLength; i++ {
  8. if i < servicesLength {
  9. // 处理服务
  10. }
  11. if i < serviceNamesLength {
  12. // 处理服务名称
  13. }
  14. }
英文:

One way you can do this is,

  1. serviceNamesLength := len(inputParameters.ServiceNames)
  2. servicesLength := len(inputParameters.Services)
  3. maxLength := serviceNamesLength
  4. if servicesLength &gt; maxLength {
  5. maxLength = servicesLength
  6. }
  7. for i := 0; i &lt; maxLength; i++ {
  8. if i &lt; servicesLength {
  9. // services stuff
  10. }
  11. if i &lt; serviceNamesLength {
  12. // services names stuff
  13. }
  14. }

答案2

得分: 0

以下是使用并发方式完成此操作的代码:

  1. func ConcurrencyLoop(inputParameters *Profile) {
  2. done := make(chan interface{})
  3. var wg sync.WaitGroup
  4. wg.Add(2)
  5. servicesNameChan := TransformServiceNames(done, inputParameters.ServiceNames, &wg)
  6. servicesInfoChan := TransformServiceInfo(done, inputParameters.Services, &wg)
  7. if servicesName, ok := <-servicesNameChan; ok {
  8. inputParameters.ServiceNames = servicesName
  9. }
  10. if servicesInfo, ok := <-servicesInfoChan; ok {
  11. inputParameters.Services = servicesInfo
  12. }
  13. close(done)
  14. wg.Wait()
  15. }
  16. func TransformServiceNames(done <-chan interface{}, servicesKey []ServiceKey, wg *sync.WaitGroup) <-chan []ServiceKey {
  17. keysChan := make(chan []ServiceKey)
  18. go func() {
  19. defer wg.Done()
  20. transformedServicekeys := make([]ServiceKey, 0)
  21. for _, serviceKey := range servicesKey {
  22. a := strings.Split(serviceKey.Service, "-")
  23. s := a[len(a)-1]
  24. transformedServicekeys = append(transformedServicekeys, ServiceKey{
  25. Service: s,
  26. })
  27. }
  28. for {
  29. select {
  30. case <-done:
  31. return
  32. case keysChan <- transformedServicekeys:
  33. }
  34. }
  35. }()
  36. return keysChan
  37. }
  38. func TransformServiceInfo(done <-chan interface{}, servicesKey []ServiceInfo, wg *sync.WaitGroup) <-chan []ServiceInfo {
  39. keysChan := make(chan []ServiceInfo)
  40. go func() {
  41. defer wg.Done()
  42. transformedServiceinfo := make([]ServiceInfo, 0)
  43. for _, serviceKey := range servicesKey {
  44. a := strings.Split(serviceKey.Service, "-")
  45. s := a[len(a)-1]
  46. transformedServiceinfo = append(transformedServiceinfo, ServiceInfo{
  47. Service: s,
  48. })
  49. }
  50. for {
  51. select {
  52. case <-done:
  53. return
  54. case keysChan <- transformedServiceinfo:
  55. }
  56. }
  57. }()
  58. return keysChan
  59. }
英文:

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

  1. func ConcurrencyLoop(inputParameters *Profile) {
  2. done := make(chan interface{})
  3. var wg sync.WaitGroup
  4. wg.Add(2)
  5. servicesNameChan := TransformServiceNames(done, inputParameters.ServiceNames, &amp;wg)
  6. servicesInfoChan := TransformServiceInfo(done, inputParameters.Services, &amp;wg)
  7. if servicesName, ok := &lt;-servicesNameChan; ok {
  8. inputParameters.ServiceNames = servicesName
  9. }
  10. if servicesInfo, ok := &lt;-servicesInfoChan; ok {
  11. inputParameters.Services = servicesInfo
  12. }
  13. close(done)
  14. wg.Wait()
  15. }
  16. func TransformServiceNames(done &lt;-chan interface{}, servicesKey []ServiceKey, wg *sync.WaitGroup) &lt;-chan []ServiceKey {
  17. keysChan := make(chan []ServiceKey)
  18. go func() {
  19. defer wg.Done()
  20. transformedServicekeys := make([]ServiceKey, 0)
  21. for _, serviceKey := range servicesKey {
  22. a := strings.Split(serviceKey.Service, &quot;-&quot;)
  23. s := a[len(a)-1]
  24. transformedServicekeys = append(transformedServicekeys, ServiceKey{
  25. Service: s,
  26. })
  27. }
  28. for {
  29. select {
  30. case &lt;-done:
  31. return
  32. case keysChan &lt;- transformedServicekeys:
  33. }
  34. }
  35. }()
  36. return keysChan
  37. }
  38. func TransformServiceInfo(done &lt;-chan interface{}, servicesKey []ServiceInfo, wg *sync.WaitGroup) &lt;-chan []ServiceInfo {
  39. keysChan := make(chan []ServiceInfo)
  40. go func() {
  41. defer wg.Done()
  42. transformedServiceinfo := make([]ServiceInfo, 0)
  43. for _, serviceKey := range servicesKey {
  44. a := strings.Split(serviceKey.Service, &quot;-&quot;)
  45. s := a[len(a)-1]
  46. transformedServiceinfo = append(transformedServiceinfo, ServiceInfo{
  47. Service: s,
  48. })
  49. }
  50. for {
  51. select {
  52. case &lt;-done:
  53. return
  54. case keysChan &lt;- transformedServiceinfo:
  55. }
  56. }
  57. }()
  58. return keysChan
  59. }

huangapple
  • 本文由 发表于 2023年2月2日 17:01:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75320763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定