在golang中,有一种方法可以映射对象数组。

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

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:

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.

huangapple
  • 本文由 发表于 2022年3月26日 10:19:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/71624828.html
匿名

发表评论

匿名网友

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

确定