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

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

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

问题

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

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

以下是结构体的定义:

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"`
}

以下是该函数的代码:

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
}

希望对你有所帮助!

英文:

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 = `
{
	&quot;ID&quot;: &quot;hgfd5432&quot;,
	&quot;Greeting&quot;: &quot;Welcome!&quot;,
	&quot;ServiceNames&quot;: [
		{
		  &quot;Service&quot;: &quot;sevice-name-service1&quot;,
		  &quot;Version&quot;: &quot;1.8&quot;
		},
		{
		  &quot;Service&quot;: &quot;sevice-name-service2&quot;,
		  &quot;Version&quot;: &quot;1.8&quot;
		},
		{
		  &quot;Service&quot;: &quot;sevice-name-service3&quot;,
		  &quot;Version&quot;: &quot;1.9&quot;
		},
		{
		  &quot;Service&quot;: &quot;sevice-name-service4&quot;,
		  &quot;Version&quot;: &quot;0.6&quot;
		}
	  ],
	  &quot;Services&quot;: [
		{
		  &quot;Service&quot;: &quot;sevice-name-service5&quot;,
		  &quot;Version&quot;: &quot;1.8&quot;
		}
		],
	&quot;BusinessUnit&quot;: &quot;Unit 1&quot;,
	&quot;Queue&quot;: &quot;UK73_Advocacy_PCCT&quot;,
	&quot;Input&quot;: &quot;Default&quot;,
  }`

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

And here is the function:

func removePrefix(inputParameters *Profile) error {

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

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

答案1

得分: 1

你可以这样做:

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

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

for i := 0; i < maxLength; i++ {
    if i < servicesLength {
        // 处理服务
    }
    if i < serviceNamesLength {
        // 处理服务名称
    }
}
英文:

One way you can do this is,

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

maxLength := serviceNamesLength
if servicesLength &gt; maxLength {
    maxLength = servicesLength
}

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

答案2

得分: 0

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

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
}

英文:

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, &amp;wg)
	servicesInfoChan := TransformServiceInfo(done, inputParameters.Services, &amp;wg)

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


	close(done)
	wg.Wait()

}

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

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

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:

确定