在golang中加入地图键

Fur*_*rge 3 go

我想将地图的所有键加入到[k1,k2,...]形式的单个字符串中.我并不过分担心订单,只是我可以制作字符串.我知道有功能,strings.Join()但它需要一个[]string而不是一个map[string]bool.

我想以最有效/最快的方式做到这一点(即我不想创建密钥的完整副本,因此我可以切片).我找不到一种方法来获得一张地图的键,所以我提出了以下功能.显然它不是最好的,因为它做了不必要的写和截断.

有没有办法只切片地图键?

func CreateStringArray(myMap map[string]bool) string {
    if myMap == nil || len(myMap) == 0 {
        return "[ ]"
    }

    buf := bytes.NewBufferString("[")

    for k, _ := range myMap {
        buf.WriteString(k)
        buf.WriteString(", ")
    }

    buf.Truncate(buf.Len() - 2)
    buf.WriteString("]")

    return buf.String()
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*kin 8

大多数时候,我只是编写明显的代码:

func KeysString(m map[string]bool) string {
    keys := make([]string, 0, len(m))
    for k := range m {
        keys = append(keys, k)
    }
    return "[" + strings.Join(keys, ", ") + "]"
}
Run Code Online (Sandbox Code Playgroud)

如果您需要的效率高于可读性,您可以查看strings.Join有关如何编写此最小化副本的想法的实现.这和你的代码之间的主要区别在于a[]byte构造完全正确的长度,它可以防止在缓冲区必须调整大小时复制数据,因为结果已经建立起来.

func KeysString(m map[string]bool) string {
    if len(m) == 0 {
        return "[]"
    }
    n := 2 * len(m)  // (len-1) commas (", "), and one each of "[" and "]".
    for k := range m {
        n += len(k)
    }
    b := make([]byte, n)
    bp := copy(b, "[")
    first := true
    for k := range m {
        if !first {
            bp += copy(b[bp:], ", ")
        }
        bp += copy(b[bp:], k)
        first = false
    }
    bp += copy(b[bp:], "]")
    return string(b)
}
Run Code Online (Sandbox Code Playgroud)

当然,请务必在您使用此功能的代码的上下文中进行分析和优化,以确保可读性权衡实际上是值得的.

  • 好吧,这与 Golang 没有真实集合的事实相结合。这意味着像 python 中的 '|'.join(set(list)) 这样简单的东西会变成:创建map[string]struct{},循环填充它,创建[]string,循环填充它,调用字符串。加入。于是一行就变成了两个循环,10行。 (2认同)