我正在使用Golang,由于某种原因,我需要合并来自不同数据库查询的结果,所有这些查询都会返回[]map[string]interface{}
我正在考虑追加,但即使有可能,它也不够清楚。
我要查看的最终数据类型是什么?

显然,以键为字符串的接口映射的数组应该能够简单地"附加"(如果有的话,可以使用concat)到另一个以键为字符串的接口映射的数组!

那么实现这一目标的机制是什么?

  • 好吧,您可以迭代:for k, v := range(map1) { map2[k] = v},但是您需要确定按键碰撞时会发生什么。 您可以使用v, ok := map2[k]; if !ok {...}检查
  • 对不起,我错过了。 您可以newslice := append(slice1, slice2...)参见blog.golang.org/slices#TOC_10。
  • 如果结果具有相同的类型[] map [string] interface {},请确保只追加结果:= append(result1,result2 ...)
  • 你是对的。 我只是尝试了一下@Uvelichitel所说的内容,并且不得不做两次(因为我有3个数组),所以它就像一个魅力! 我应该把它作为答案吗?
  • 实际上,该问题应重新编写以匹配gos语法和功能。 对于问题,对于切片而言,包含图都是无关紧要的。 您可以对任何切片类型(例如[]byte)执行相同的操作。 多数民众赞成在内部函数append是什么,这就是如何记录它(附加和复制切片)。

甚至在上面的评论中已经给出了答案,我将发布一个简短的示例来说明如何实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package main

import (
   "fmt"
)

func main() {
    result := []map[string]interface{}{}

    mp1 := map[string]interface{}{
       "one" : 1,
       "two" : 2,
    }

    mp2 := map[string]interface{}{
       "three" : 3,
       "four" : 4,
    }

    mp3 := make(map[string]interface{})
    for k, v := range mp1 {
        if _, ok := mp1[k]; ok {
            mp3[k] = v          
        }
    }

    for k, v := range mp2 {
        if _, ok := mp2[k]; ok {
            mp3[k] = v
        }
    }

    result = append(result, mp1, mp2)
    fmt.Println(result)
}

输出将是:

1
[map[one:1 two:2] map[three:3 four:4]]

游乐场的例子

  • 荣誉!就我而言,我具有map1,map2和map3的所有[] map [string] interface {}类型,并且得到了-result:= map1 result = append(result,map2 ...)result = append(result,map3)。 ..)那正是我所需要的!

另一个答案是正确的。 您还可以编写一个辅助函数来避免重复的地图合并。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// overwriting duplicate keys, you should handle that if there is a need
func mergeMaps(maps ...map[string]interface{}) map[string]interface{} {
    result := make(map[string]interface{})
    for _, m := range maps {
        for k, v := range m {
            result[k] = v
        }
    }
    return result
}

func main() {
    log.Println(`started`)

    v := []map[string]interface{}{
        map[string]interface{}{
            `one`: 1,
            `two`: 2,
        },
        map[string]interface{}{
            `one`:   `I`,
            `three`: 3,
            `other`: `NAN`,
        },
        map[string]interface{}{
            `name`: `Bob`,
            `age`:  300,
        },
    }

    m := mergeMaps(v...)
    log.Println(m, len(m))
}
  • 从长远来看是有意义的,并且很有用!谢谢!
  • 请注意,这是完全不同的操作类型! append在片上运行。如果合并两个映射,则可以定义两个不同的合并操作(A := A MERGE B),其中B [k]覆盖A [k],另一个定义中A [k]保留其在B [k]上的值。
  • 没错,这就是为什么这个答案以"另一个答案正确"开头。尽管除了处理json(或一些外部数据流)以外,拥有"切片图"是一些常见的错误,并且mp3实际上并没有在第一个答案中的任何地方使用。
  • 就我个人而言,我更喜欢您的解决方案,因为在我的用例中,我实际上希望后续映射(用于存储来自多个源的各种配置变量)覆盖存储在第一个映射上的默认配置。对于这种用法,这是完美的!谢谢 ??