Golang如何根据目标索引切片重新排序而无需循环
Golang如何根据目标索引切片重新排序而无需循环 考虑以下两个切片
x := []int{10, 20, 30}
idx := []int{0, 2, 1}
我能否在不使用循环的情况下,使用 idx 作为期望的顺序(即 [10, 30, 20])来重新排序切片 x?
目前我的做法是
x := []int{10, 20, 30}
idx := []int{0, 2, 1}
var result []int
for _, s := range idx {
result = append(result, x[s])
}
在其他语言(例如 R、Julia 等)中,你只需要执行 x[idx]。
更多关于Golang如何根据目标索引切片重新排序而无需循环的实战教程也可以访问 https://www.itying.com/category-94-b0.html
和你一起数数… 哈哈
感谢您的解释。
确实,正如 @mje 所指出的,对于像我这样并非全天候使用 Go 进行编码的人来说,重写代码确实有点烦人 😛
就像在R或Julia中一样。
不同之处在于,在泛型出现之前,你必须为每种切片类型重写那段代码。
// 示例代码:为每种切片类型重写
func processIntSlice(slice []int) {
// 处理整数切片
}
func processStringSlice(slice []string) {
// 处理字符串切片
}
你好 @Pisistrato,
其他语言内置了大量便捷函数、魔法命令和快捷方式,以使编写代码变得舒适,但代价是让阅读变得更加隐晦。
Go 并非如此。但你可以将循环放入一个函数中,这样就能实现无需循环的切片重排,就像在 R 或 Julia 中一样。 🙂
(为了解释我所说的让阅读更隐晦是什么意思:对我来说,x[idx] 看起来完全像 Go 中一个简单的索引操作。如果这个语法表示基于 idx 对 x 进行完全重组,并且预期 idx 的内容是一组唯一的整数,那么这就是大量上下文信息被塞进了表达式 x[idx] 中。我更愿意用一个恰当的名称来阅读这个操作,例如 x.ReorderBy(idx)。)
在Go中,你可以使用map和切片组合来实现类似x[idx]的效果,但本质上仍然涉及循环。不过,你可以通过append和range来简化代码,避免显式的for循环索引。以下是示例代码:
package main
import "fmt"
func main() {
x := []int{10, 20, 30}
idx := []int{0, 2, 1}
result := make([]int, len(idx))
for i, v := range idx {
result[i] = x[v]
}
fmt.Println(result) // 输出: [10 30 20]
}
如果你希望更简洁,可以使用函数式风格,但Go标准库没有内置的类似map的高阶函数。你可以使用第三方库如github.com/thoas/go-funk,但这样会引入外部依赖。以下是使用go-funk的示例:
package main
import (
"fmt"
"github.com/thoas/go-funk"
)
func main() {
x := []int{10, 20, 30}
idx := []int{0, 2, 1}
result := funk.Map(idx, func(i int) int {
return x[i]
}).([]int)
fmt.Println(result) // 输出: [10 30 20]
}
注意:go-funk内部仍然使用循环,但代码看起来更简洁。在Go中,直接使用循环通常是最高效和清晰的方式。

