简体   繁体   English

如何获取地图的所有键和值并作为args传递给golang中的函数?

[英]How to take all keys and values of a map and pass as args to a function in golang?

I encountered such a situation: 我遇到过这样的情况:

Got a map first, and its size is unknown . 先得到一张地图, 其大小未知

Eg: myMap map[string]string 例如: myMap map[string]string

And then, I would take all the keys and values of the map as a function's args 然后,我将把地图的所有键和值作为函数的args

eg func(key1, key2, ..., value1, value2, ...) 例如func(key1, key2, ..., value1, value2, ...)

An example func: https://godoc.org/github.com/garyburd/redigo/redis#Script.Do 一个示例func: https//godoc.org/github.com/garyburd/redigo/redis#Script.Do

How to achieve this in go? 如何实现这一目标?

As efficient as impossible. 尽可能高效。

Any help will be appreciated :) 任何帮助将不胜感激 :)

We can query the length of the map with the builtin len() function. 我们可以使用builtin len()函数查询地图的长度。 So we can create a big-enough slice to hold all the keys and all the values. 因此,我们可以创建一个足够大的切片来保存所有键和所有值。

After that it's enough to iterate over the map only once, and you can fill the first half of the slice with the keys, and the second half of the slice with the values. 之后,仅在地图上迭代一次就足够了,您可以使用键填充切片的前半部分,并使用值填充切片的后半部分。

This is as efficient as it can get: no builtin append() is called, and we iterate over the map only once. 这是有效的:没有内置的append()被调用,我们只在地图上迭代一次。

Let's see an example function that will receive the keys and values. 让我们看一个将接收键和值的示例函数。 This one just prints all of them: 这个只打印所有这些:

func pairs(keysvalues ...string) {
    for _, s := range keysvalues {
        fmt.Print(s, ", ")
    }
}

And the code that creates the keysvalues slice: 以及创建keysvalues切片的代码:

m := map[string]string{
    "a": "A",
    "b": "B",
    "c": "C",
}

count := len(m)
all := make([]string, count*2)

i := 0
for k, v := range m {
    all[i], all[count+i] = k, v
    i++
}

Once you have the all slice, you can call the pairs() function like this: 获得all slice后,可以像这样调用pairs()函数:

pairs(all...)

Note though that the iteration order over a map is not deterministic, it may change from iteration to iteration. 请注意,虽然地图上的迭代顺序不是确定性的,但它可能会从迭代变为迭代。

Example output (try it on the Go Playground ): 示例输出(在Go Playground上尝试):

a, b, c, A, B, C, 

Note: 注意:

In your question you indicated that all keys come first and then follow all the values: 在您的问题中,您表示所有密钥首先出现,然后遵循所有值:

 func(key1, key2, ..., value1, value2, ...) 

In practice this is rare and often the key-value pairs are listed. 在实践中,这很少见,并且通常会列出键值对。 It's much easier to work/process this variant: 处理/处理此变体要容易得多:

func pairs(key1, value1, key2, value2, ... keyn, valuen)

If we would want to produce this key-value pair list, very similarly it would look like this: 如果我们想要生成这个键值对列表,非常相似它看起来像这样:

count := len(m)
all := make([]string, count*2)

i := 0
for k, v := range m {
    all[i], all[i+1] = k, v
    i += 2
}

For example, 例如,

package main

import "fmt"

func fn(args ...string) { fmt.Println(args) }

func main() {
    m := map[string]string{"k1": "v1", "k2": "v2"}
    args := make([]string, 0, 2*len(m))
    for key, value := range m {
        args = append(args, key)
        args = append(args, value)
    }
    fmt.Println(args)
    fn(args...)
}

Output: 输出:

[k1 v1 k2 v2]
[k1 v1 k2 v2]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM