英文:
Is there a way to map an array of objects in golang?
问题
从Node.js过来,我可以这样做:
// 假设有一个包含字段`fruit`的对象数组`list`:
fruits := make([]string, len(list))
for i, el := range list {
fruits[i] = el.fruit
}
有没有一种优雅的一行代码解决方案在Go语言中实现这个功能?
我知道可以用range循环来实现,但我想知道是否有可能用一行代码解决。
英文:
Coming from Nodejs, I could do something like:
// given an array `list` of objects with a field `fruit`:
fruits = list.map(el => el.fruit) # which will return an array of fruit strings
Any way to do that in an elegant one liner in golang?
I know I can do it with a range loop, but I am looking for the possibility of a one liner solution
答案1
得分: 20
在Go语言中,数组是不灵活的(因为它们的长度被编码在它们的类型中),并且将数组传递给函数的成本很高(因为函数对其数组参数的操作是在副本上进行的)。我假设您希望对切片而不是数组进行操作。
因为方法不能接受额外的类型参数,所以您不能在Go中简单地声明一个通用的Map
方法。但是,您可以将Map
定义为一个通用的顶级函数:
func Map[T, U any](ts []T, f func(T) U) []U {
us := make([]U, len(ts))
for i := range ts {
us[i] = f(ts[i])
}
return us
}
然后,您可以编写以下代码:
names := []string{"Alice", "Bob", "Carol"}
fmt.Println(Map(names, utf8.RuneCountInString))
它会将[5 3 5]
打印到标准输出(在此 Playground中尝试一下)。
Go 1.18引入了golang.org/x/exp/slices包,该包提供了许多方便的切片操作,但是其中明显缺少一个Map
函数。省略该函数是在与golang.org/x/exp/slices
提案相关的GitHub问题的长时间讨论的结果;其中涉及以下问题:
Russ Cox 最终决定从提案中删除Map
,因为它
> 可能更适合作为更全面的流API的一部分出现在其他地方。
英文:
In Go, arrays are inflexible (because their length is encoded in their type) and costly to pass to functions (because a function operates on copies of its array arguments). I'm assuming you'd like to operate on slices rather than on arrays.
Because methods cannot take additional type arguments, you cannot simply declare a generic Map
method in Go. However, you can define Map
as a generic top-level function:
func Map[T, U any](ts []T, f func(T) U) []U {
us := make([]U, len(ts))
for i := range ts {
us[i] = f(ts[i])
}
return us
}
Then you can write the following code,
names := []string{"Alice", "Bob", "Carol"}
fmt.Println(Map(names, utf8.RuneCountInString))
which prints [5 3 5]
to stdout (try it out in this Playground).
Go 1.18 saw the addition of a golang.org/x/exp/slices
package, which provides many convenient operations on slices, but a Map
function is noticeably absent from it. The omission of that function was the result of a long discussion in the GitHub issue dedicated to the golang.org/x/exp/slices
proposal; concerns included the following:
- hidden cost (O(n)) of operations behind a one-liner
- uncertainty about error handling inside
Map
- risk of encouraging a style that strays too far from Go's traditional style
Russ Cox ultimately elected to drop Map
from the proposal because it's
> probably better as part of a more comprehensive streams API somewhere else.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论