如何在 go 中为哈希映射创建复合键

首先,我对组合键的定义——两个或多个值组合起来构成键。不要与数据库中的复合键混淆。

我的目标是将 的计算值保存pow(x, y)在哈希表中,其中xy是整数。这是我需要关于如何制作密钥的想法的地方,以便给定xy,我可以在哈希表中查找它,找到pow(x,y).

例如:

pow(2, 3) => {key(2,3):8}

我想弄清楚的是如何获取 pair 的映射键(2,3),即生成一个键的最佳方法,该键是多个值的组合,并在哈希表中使用它。


尚方宝剑之说
浏览 137回答 3
3回答

慕村9548890

最简单和最灵活的方法是使用 astruct作为键类型,包括您希望成为键一部分的所有数据,因此在您的情况下:type Key struct {    X, Y int}就这样。使用它:m := map[Key]int{}m[Key{2, 2}] = 4m[Key{2, 3}] = 8fmt.Println("2^2 = ", m[Key{2, 2}])fmt.Println("2^3 = ", m[Key{2, 3}])输出(在Go Playground上尝试):2^2 =  4 2^3 =  8规范:映射类型:您可以使用任何类型作为比较运算符==和!=完全定义的键,上面的Key结构类型实现了这一点。规范:比较运算符:如果结构值的所有字段都是可比较的,则结构值是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。一件重要的事情:你不应该使用指针作为键类型(例如*Key),因为比较指针只比较内存地址,而不是指向的值。另请注意,您也可以使用数组(不是slices)作为键类型,但数组不如结构灵活。您可以在此处阅读这就是数组的样子:type Key [2]intm := map[Key]int{}m[Key{2, 2}] = 4m[Key{2, 3}] = 8fmt.Println("2^2 = ", m[Key{2, 2}])fmt.Println("2^3 = ", m[Key{2, 3}])输出是一样的。

宝慕林4294392

Go 无法对一片整数进行散列。因此,我采用的方法是将结构映射到数字。这是一个如何做到这一点的例子:package mainimport (    "fmt")type Nums struct {    num1 int    num2 int}func main() {    powers := make(map[Nums]int)    numbers := Nums{num1: 2, num2: 4}    powers[numbers] = 6    fmt.Printf("%v", powers[input])}我希望这有帮助

侃侃尔雅

其他答案很好地解决了您的具体问题。我想添加一个在某些极端情况下可能有用的额外技巧。鉴于映射键必须是可比较的,您还可以使用接口。如果接口的动态值是可比较的,则接口是可比较的。这允许您从本质上对映射进行分区,即在同一数据结构中使用多种类型的键。例如,如果您想在地图中存储 n 元组(它不适用于数组,因为数组长度是类型的一部分)。这个想法是用一个虚拟方法定义一个接口(但它肯定不是虚拟的),并将其用作映射键:type CompKey interface {    isCompositeKey() bool}var m map[CompKey]string此时,您可以让任意类型实现接口,无论是显式实现还是仅通过嵌入实现。在这个例子中,想法是使接口方法不被导出,这样其他结构就可以嵌入接口而不必提供实际的实现——不能从其包外部调用该方法。它只会发出该结构可用作复合映射键的信号。type AbsoluteCoords struct {    CompKey    x, y int}type RelativeCoords struct {    CompKey    x, y int}func foo() {    p := AbsoluteCoords{x: 1, y: 2}    r := RelativeCoords{x: 10, y: 20}    m[p] = "foo"    m[r] = "bar"    fmt.Println(m[AbsoluteCoords{x: 10, y: 20}]) // "" (empty, types don't match)        fmt.Println(m[RelativeCoords{x: 10, y: 20}]) // "bar" (matches, key present)}当然,没有什么能阻止您在界面上声明实际的方法,这在遍历地图键时可能很有用。这个接口键的缺点是现在你有责任确保实现类型实际上是可比较的。例如这个地图键会恐慌:type BadKey struct {    CompKey    nonComparableSliceField []int}b := BadKey{nil, []int{1,2}}m[b] = "bad!" // panic: runtime error: hash of unhashable type main.BadKey总而言之,当您需要在同一映射中保留两组 K/V 对时,这可能是一种有趣的方法,例如,为了保持函数签名的完整性或避免定义具有 N 个非常相似的映射字段的结构。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go