golang convert slice{0,1,2,3,4} to slice{1,2,3}?

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

golang convert slice{0,1,2,3,4} to slice{1,2,3}?

问题

我有一个动态字符串切片,例如{"0s", "1s", "2s", "3s", "4s"}。
我还有一个动态索引切片,例如{1, 2, 3}。
所以我只需要切片中索引为1、2和3的元素。
注意,索引切片和数据切片都是动态的。

package main

import (
	"fmt"
)

func main() {
	indexes := []uint8{1, 2, 3}              //动态切片。可能有不同的元素和数量
	data := []string{"0s", "1s", "2s", "3s", } //动态切片。可能有不同的元素和数量

	// 我需要使用索引(动态切片)将数据转换为{"1s", "2s", "3s"}
	fmt.Println(data)
	fmt.Println(indexes)
}

这是playground的链接:https://play.golang.org/p/Vj0Vl5va4LP

英文:

I have dynamic slice of strings for example {"0s", "1s", "2s", "3s", "4s"}.
And I have dynamic slice of indexes for example {1, 2, 3}.
So i need only elements with index 1, 2 and 3 in slice.
Note both indexes slice and data slice are dynamic.

package main

import (
	"fmt"
)

func main() {
	indexes := []uint8{1, 2, 3}              //dynamic slice. maybe different elements and count
	data := []string{"0s", "1s", "2s", "3s", } //dynamic slice. maybe different elements and count

	// I need convert data to {"1s", "2s", "3s"} using indexes (dynamic) slice
	fmt.Println(data)
	fmt.Println(indexes)
}

here playground url https://play.golang.org/p/Vj0Vl5va4LP

答案1

得分: 8

创建一个新的数据切片,其中的索引值是从索引切片中获取的,你需要遍历索引切片,并将索引切片的值作为数据切片的索引。以下是使用这种逻辑的代码:

package main

import (
	"fmt"
)

func main() {
	indexes := []uint8{1, 2, 3}
	data := []string{"0s", "1s", "2s", "3s"}
	var newData []string

	fmt.Println(data)
	fmt.Println(indexes)

	for _, v2 := range indexes {
		newData = append(newData, data[v2])
	}
	fmt.Println(newData)
}

输出结果:

[0s 1s 2s 3s]
[1 2 3]
[1s 2s 3s]
英文:

To create a new data slice with index values retrieved from index slice ,you have to iterate the index slice and pass the value of index slice as index of data slice.Below is the code with this logic

package main

import (
	"fmt"
)

func main() {
	indexes := []uint8{1, 2, 3}
	data := []string{"0s", "1s", "2s", "3s"}
	var newData []string

	fmt.Println(data)
	fmt.Println(indexes)

	for _, v2 := range indexes {

		newData = append(newData, data[v2])
	}
	fmt.Println(newData)
}

Output :

[0s 1s 2s 3s]
[1 2 3]
[1s 2s 3s]

答案2

得分: 4

请注意 - 您的索引切片的类型是[]uint8 - 这是可以的,但是限制了您的切片最大长度为256。这可能是有意为之,但只是需要注意。

这里的其他解决方案使用了append - 对于小切片来说是可以的。但是一般来说,当处理切片时,如果您知道最终切片的长度,最好预先分配空间并直接写入索引,避免append可能执行多次重新分配:

func correlate(vs []string, is []uint8) (s []string) {
    s = make([]string, len(is)) // 预先分配结果的长度 - 避免使用append

    for j, i := range is {
        s[j] = vs[i]
    }
    return
}

https://play.golang.org/p/Et2VyoZzo59

英文:

Please note - your index slice is of type []uint8 - which is fine, but limits you to slices of max-length 256. This may be by design, but just something to be aware of.

Other solutions here use append - which is fine for small slices. But in general, when dealing with slices, if you know the final slice length, it is best to pre-allocate and write directly to indices and avoid append potentially performing multiple reallocations:

func correlate(vs []string, is []uint8) (s []string) {
	s = make([]string, len(is)) // pre-allocate results length - to avoid using append

	for j, i := range is {
		s[j] = vs[i]
	}
	return
}

https://play.golang.org/p/Et2VyoZzo59

答案3

得分: 2

这里是一个通用解决方案,它只检索匹配的元素,并且如果超出范围则丢弃。

func getElementsByIndexes(data []string, indexes []uint8) []string {
    res := make([]string, 0)
    l := len(data)
    
    for _, v := range indexes {    
        // 如果超出范围则丢弃
        if int(v) >= l {
            continue
        }
    
        res = append(res, data[int(v)])
    }

    return res
}
英文:

Here is a general solution that retrieves only the matched elements and discard if out of range.
https://play.golang.org/p/34vQnNh0jd4

func getElementsByIndexes(data []string, indexes []uint8) []string {
	res := make([]string, 0)
	l := len(data)
	
	for _, v := range indexes {	
        // discard if out of range
	    if int(v) >= l {
		    continue
	    }
	
	    res = append(res, data[int(v)])
	}

	return res
}

</details>



# 答案4
**得分**: 0

我来翻译一下:

我找到了一个相当简单的解决方案:

```go
func filterByIndexes(sl []string, ind []int) []string {
    var filteredSlice []string
    for index := range ind {
        // 你可能想要检查索引是否超出范围 :)
        filteredSlice = append(filteredSlice, sl[index])
    }
    return filteredSlice
}

如注释所述,你可能想要检查索引是否超出范围!

英文:

i came to this pretty simple solution:

func filterByIndexes(sl []string, ind []int)[]string{
var filteredSlice []string
for index := range ind{
	// you may want to check for index out of range :)
	filteredSlice = append(filteredSlice, sl[index])
}
return filteredSlice

}

As commented, you may want to check for index out of range!

huangapple
  • 本文由 发表于 2021年5月31日 18:38:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/67772190.html
匿名

发表评论

匿名网友

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

确定