Go每日一题(8) 的题目如下

4815 次点击 · 6 赞 ·大约8小时之前 开始浏览   · 来源「Go Questions」

如何确认两个 map 是否相等?

4815 阅读
48 回复
xwszt
xwszt · #1 · 3年之前

map是无序存储的,所以不能直接判断两个map是否相等;网上有一种比较方法,不一定是最好,但起码也是一种方案。

func CompareMap(dm1 map[string]interface{}, dm2 map[string]interface{}) bool {
    keySlice := make([]string, 0)
    data1Slice := make([]interface{}, 0)
    data2Slice := make([]interface{}, 0)
    for key, value := range dm1 {
        keySlice = append(keySlice, key)
        data1Slice = append(data1Slice, value)
    }
    for _, key := range keySlice {
        if data, ok := dm2[key]; ok {
            data2Slice = append(data2Slice, data)
        } else {
            return false
        }
    }
    data1Bytes, _ := json.Marshal(data1Slice)
    data2Bytes, _ := json.Marshal(data2Slice)
    return string(data1Bytes) == string(data2Bytes)
}

代码中遗漏了判断两个map是否为nil以及是否长度相等的前置条件判断,大概思路就是取出其中一个map的key放到slice里,并且按照key的slice到另外一个map中取值,如果有一个取不到,那这两个map肯定不相等,如果都取到了,那么比较两个dataslice的json编码是否相等

Ge-go
Ge-go · #2 · 3年之前

package main

import ( "fmt" "reflect" )

func main() { //定义两个map m := make(map[string]string) m1 := make(map[string]string)

m["name"] = "wangshao"
m["age"] = "15"
m["sex"] = "man"

m1["name"] = "wangshao"
m1["age"] = "15"
m1["sex"] = "man"

//先遍历一个map拿出所有的key
k := make([]string, 0)
v := make([]string, 0)
for key, value := range m {
    k = append(k, key)
    v = append(v, value)
}

if len(m) == len(m1) {
    for i := 0; i < len(k); i++ {
        if m1[k[i]] == v[i] {
            fmt.Println("same")
        } else {
            fmt.Println("no same")
        }
    }
}

//反射方式
fmt.Println(reflect.DeepEqual(m, m1))

}

jarlyyn
jarlyyn · #3 · 3年之前

先要确定一个问题

为什么确认两个map相等

怎么算相等

liangmanlin
liangmanlin · #4 · 3年之前

标准答案可能不太方便,我认为,反射更加合理


package main

import( 
    "fmt"
    "relflect"
)
func main() {
    var m map[string]int
    var n map[string]int

    fmt.Println(reflect.DeepEqual(m,n))
}
Ge-go
Ge-go · #5 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

牛逼

hongtj
hongtj · #6 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

👍

realv5
realv5 · #7 · 3年之前

笨办法,循环判断每一个key和每个key的值

Natsuwau
Natsuwau · #8 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

🐮

henry1
henry1 · #9 · 3年之前

OK

neil_liu
neil_liu · #10 · 3年之前

m

minQie
minQie · #11 · 3年之前

di

Dessert
Dessert · #12 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

niu

feiyang
feiyang · #13 · 3年之前

打卡

gonglf
gonglf · #14 · 3年之前

map是无序存储的,所以不能直接判断两个map是否相等;网友说可以使用reflect.DeepEqual反射来判断是否相等

Rob1n
Rob1n · #15 · 3年之前

m

NovaChaos
NovaChaos · #16 · 3年之前

mk

feiyang
feiyang · #17 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

大佬牛

Neightly
Neightly · #18 · 3年之前

凭什么先对问题做一个假设,不是string就是int? 有没有想过为什么会有hashMightPanic?因为map不只是string、int,还有interface呢。 hash可能panic,compare也是可能panic的。结论可不只是true/false,panic不能忽略。

hasbug
hasbug · #19 · 3年之前

mark

Zuos
Zuos · #20 · 3年之前

mark

Dessert
Dessert · #21 · 3年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

感谢,reflect.DeepEqual比较map

wzbwzt
wzbwzt · #22 · 3年之前

1

big_cat
big_cat · #23 · 3年之前
// EqualMap 比较 map 是否相等(只适用成员为标量的map)
func EqualMap(m1, m2 map[string]interface{}) bool {
    if (0 == len(m1) && 0 == len(m2)) || (nil == m1 && nil == m2) {
        return true
    }
    var keys1 []string
    for key, _ := range m1 {
        keys1 = append(keys1, key)
    }
    var keys2 []string
    for key, _ := range m2 {
        keys2 = append(keys2, key)
    }
    for _, key := range keys1 {
        if v2, ok := m2[key]; ok && m1[key] == v2 {
            continue
        }
        return false
    }
    return true
}

// EqualMapReflect 比较 map 是否深相等
func EqualMapReflect(m1, m2 map[string]interface{}) bool {
    if (0 == len(m1) && 0 == len(m2)) || (nil == m1 && nil == m2) {
        return true
    }
    return reflect.DeepEqual(m1, m2)
}
a406299736
a406299736 · #24 · 3年之前

mark///////.......

NovaChaos
NovaChaos · #25 · 3年之前

mk

a406299736
a406299736 · #26 · 3年之前

打开

a406299736
a406299736 · #27 · 3年之前

mark

brothersam
brothersam · #28 · 3年之前

双方都遍历互相比对,碰到下一级是map 或 slice,再遍历。。。。

hasbug
hasbug · #29 · 3年之前

mark

jatshw
jatshw · #30 · 3年之前

m

wzbwzt
wzbwzt · #31 · 3年之前

1

suzhenyu
suzhenyu · #32 · 3年之前
  1. 官网文档规定,slice, map, 和 function 之间不能直接比较是否相等,特例是 nil。具体参照:https://go.dev/ref/spec#Comparison_operators
  2. Go 中 map 的 value 类型可以是任意类型的,这就把上面除了『reflect.DeepEqual』之外的其他方法几乎都毙掉了,因为要判断value 类型是 slice、map 或 function 的话该如何处理。要自己实现的话,其实参照 reflect.DeepEqual 的实现来比较好。
feiyang
feiyang · #33 · 3年之前

第二次打卡:如何确认两个 map 是否相等?

bsdx866
bsdx866 · #34 · 2年之前

image.png

brothersam
brothersam · #35 · 2年之前

反射:reflect.DeepEqual(m1,m2)

Dessert
Dessert · #36 · 2年之前

4楼 @liangmanlin 反射判断深度相等

map 深度相等的条件:

都为 nil; 非空、长度相等,指向同一个 map 实体对象; 相应的 key 指向的 value “深度”相等

a406299736
a406299736 · #37 · 2年之前

1111111111

Ysmword
Ysmword · #38 · 2年之前

反射,或者遍历

feiyang
feiyang · #39 · 2年之前

如何确认两个 map 是否相等?

Dessert
Dessert · #40 · 2年之前
liangmanlinliangmanlin #4 回复

标准答案可能不太方便,我认为,反射更加合理 ```golang package main import( "fmt" "relflect" ) func main() { var m map[string]int var n map[string]int fmt.Println(reflect.DeepEqual(m,n)) } ```

nice

Linyuqiz
Linyuqiz · #41 · 2年之前

m := make(map[string]string) n := make(map[string]string) if maps.Equal(m, n) { println("equal") }

RobKing9
RobKing9 · #42 · 2年之前

func isSame(m1, m2 map[int]int) bool { // 长度 if len(m1) != len(m2) { return false } // 每个值 for k1, v1 := range m1 { // 在m2是否存在 并且 相等 v2, exist := m2[k1] if !exist || v2 != v1 { return false } } return true }

大佬们看看这种方法怎么样?

RobKing9
RobKing9 · #43 · 2年之前

image.png

大佬们看看这种方法怎么样?

agree
agree · #44 · 2年之前
RobKing9RobKing9 #43 回复

![image.png](https://static.golangjob.cn/230826/08093b9ce66a0056f5c247b9d40e9773.png) 大佬们看看这种方法怎么样?

条件限制比较死,只能用于v1、v2可以直接用==判断相等的情况

liapples
liapples · #45 · 大约1年之前
RobKing9RobKing9 #43 回复

![image.png](https://static.golangjob.cn/230826/08093b9ce66a0056f5c247b9d40e9773.png) 大佬们看看这种方法怎么样?

这只能判断int类型。value如果是struct,map,slice其它类型就无法判断了

528548004
528548004 · #46 · 大约1年之前

mark

WangWangZhou
WangWangZhou · #47 · 9月之前

mark

YuPeng
YuPeng · #48 · 5月之前

1.23 maps 包有提供判定方法了

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传