有没有办法在 Go 中映射对象数组?

问题描述 投票:0回答:2

来自 Node.js,我可以做类似的事情:

// given an array `list` of objects with a field `fruit`:

fruits = list.map(el => el.fruit) # which will return an array of fruit strings 

有什么方法可以用 Go 中的优雅单行来做到这一点吗?

我知道我可以用范围循环来做到这一点,但我正在寻找单行解决方案的可能性。

go generics higher-order-functions
2个回答
30
投票

在 Go 中,数组不灵活(因为它们的长度是在其类型中编码的)并且传递给函数的成本很高(因为函数对其数组参数的副本进行操作)。我假设您想对 slices 进行操作,而不是对数组进行操作。

因为 方法不能接受额外的类型参数,所以你不能简单地在 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]
打印到标准输出(在 this Playground 中尝试一下)。


Go 1.18 添加了

golang.org/x/exp/slices
,它为切片提供了许多方便的操作,但明显缺少
Map
函数。该功能的省略是专门针对 golang.org/x/exp/slices 提案的
GitHub issues
进行长时间讨论的结果;担忧包括以下内容:

Russ Cox 最终 选择从提案中删除

Map
,因为它

作为其他地方更全面的流 API 的一部分可能会更好。


-1
投票

我不确定你指的是“地图”这个词。在 golang 中,map 类似于字典,其中有键和值

map[key]value

Bellow 是一个辅助函数(必须转到 maps 包),它允许在 go 中创建地图:

func Map[T, K comparable, V any](arr []T, f_key func(T) K, f_val func(T) V) map[K]V {
    m := make(map[K]V, len(arr))
    for i := range arr {
        m[f_key(arr[i])] = f_val(arr[i])
    }
    return m
}

// Usage
var m = Map(books, 
    func(b Book) string { return b.Id }, 
    func(b Book) Book { return b }
)

请参阅游乐场:https://go.dev/play/p/Bak3gfY0UV0

nodejs 中的

map
是一个函数,它允许遍历元素并在*一行中构建您自己的类型。在这种情况下,请参阅@jub0bs答案https://stackoverflow.com/a/71624929/1143349

© www.soinside.com 2019 - 2024. All rights reserved.