如果有两个map,内容都一样,只有顺序不同

m1:=map[string]int{"a":,"b":,"c":};
m2:=map[string]int{"a":,"c":,"b":};

我们怎么判断二者是否一致呢?

如果你打算这么写:

fmt.Println("m1==m2",m1==m2)

这是行不通的,go没有重写map的==操作符,编译器会报告错误:

 invalid operation: m1 == m2 (map can only be compared to nil)

意思是map的变量只能和空(nil)比较,例如:

fmt.Println("m1 == nil?",m1==nil)
fmt.Println("m2 != nil?",m2!=nil)

这没有问题,执行结果是:

Running...

m1 == nil? false
m2 != nil? true

那怎么比较呢?如果要编程实现,还真是麻烦,比如我的想法是:循环m1,看看每个key是否都在m2中存在,再比较m1[key]是否和m2[key]相等,如果都ok,再依次循环m2。还真是麻烦:

func cmpMap(m1,m2  map[string]int)bool{
for k1,v1 :=range m1{
if v2,has:=m2[k1];has{
if v1!=v2 {
return false
}
}else{
return false;
}
}
for k2,v2:=range m2{
if v1,has:=m1[k2];has{
if v1!=v2{
return false;
}
}else{
return false;
}
}
return true;
}

其实,go的反射包中有一个巨好用的武器reflect.DeepEqual,可以方便解决这个问题,请看:

package main

import(
"fmt" "reflect"
)
type tt struct{
Code int
}
func main(){
m1:=map[string]int{"a":,"b":,"c":};
m2:=map[string]int{"a":,"c":,"b":}; fmt.Println("m1 == nil?",m1==nil)
fmt.Println("m2 != nil?",m2!=nil)
//fmt.Println("m1==m2",m1==m2)
fmt.Println("cmpMap(m1,m2) = ",cmpMap(m1,m2));
fmt.Println("reflect.DeepEqual(m1,m2) = ",reflect.DeepEqual(m1,m2))
fmt.Println()
m3:=map[string]int{"a":,"b":,"c":,"d":};
fmt.Println("cmpMap(m1,m3)=",cmpMap(m1,m3));
fmt.Println("reflect.DeepEqual(m1,m3) = ",reflect.DeepEqual(m1,m3))
}
func cmpMap(m1,m2 map[string]int)bool{
for k1,v1 :=range m1{
if v2,has:=m2[k1];has{
if v1!=v2 {
return false
}
}else{
return false;
}
}
for k2,v2:=range m2{
if v1,has:=m1[k2];has{
if v1!=v2{
return false;
}
}else{
return false;
}
}
return true;
}

执行结果:

Running...

m1 == nil? false
m2 != nil? true
cmpMap(m1,m2) = true
reflect.DeepEqual(m1,m2) = true cmpMap(m1,m3)= false
reflect.DeepEqual(m1,m3) = false Success: process exited with code .

但是美中不足的是,由于reflect.DeepEqual需要经过反射操作,效率比我们自己写的函数差的多了,写个简单的测试:

        start:=time.Now();
for i:=0;i<100000;i++{
cmpMap(m1,m2)
}
end:=time.Now();
du:=end.Sub(start)
fmt.Println("100000 call cmpMap(m1,m2) elapsed=",du) start=time.Now();
for i:=0;i<100000;i++{
reflect.DeepEqual(m1,m2);
}
end=time.Now();
du=end.Sub(start);
fmt.Println("100000 call reflect.DeepEqual(m1,m2) elapsed=",du)

看看结果,大约有10倍的差距

 call cmpMap(m1,m2) elapsed= .544992ms
call reflect.DeepEqual(m1,m2) elapsed= .577069ms

当然,在一般情况下,这点儿性能损失不算什么,尤其在不确定类型需要反射的时候,更是我们不可不用的强大工具。

比如:

func main(){
m1:=map[string]interface{}{"a":"", "b":, "c":};
m2:=map[string]interface{}{"a":, "c":"", "b":}; fmt.Println(`reflect.DeepEqual(m1["a"],m2["a"]`,reflect.DeepEqual(m1["a"],m2["a"]));
fmt.Println(`reflect.DeepEqual(m1["b"],m2["b"]`,reflect.DeepEqual(m1["b"],m2["b"]));
}

执行结果:

Running...

reflect.DeepEqual(m1["a"],m2["a"] false
reflect.DeepEqual(m1["b"],m2["b"] true

这种情况,如果我们自己写代码比较,势必要使用switch type语法,实在是太麻烦了,感谢go包含了这么好的工具。

最新文章

  1. 深入java集合学习2-ArrayList的实现原理
  2. MyEclipse部署到tomcat的问题
  3. java程序故障排查脚本之——CPU占用高
  4. [cocoapods]cocoapods问题解决
  5. instancetype vs id for Objective-C
  6. 转:40多个关于人脸检测/识别的API、库和软件
  7. android Animation动画的xml使用
  8. Express安装
  9. git命令提交新项目
  10. FormsAuthentication 票据前后台登录导致掉线
  11. fastJson 之 JSONPath使用
  12. what&#39;s the 颈线
  13. rabbitmq用户授权
  14. 【逆向笔记】OD工具使用-逆向TraceMe.exe
  15. Python实现简单的udp打洞(P2P)
  16. JAVA JDK的安装及初步试用
  17. 【PAT】1020 Tree Traversals (25)(25 分)
  18. Visual Studio 2012创建SQL Server Database Project提示失败解决方法
  19. easyui---基础组件:dialog
  20. JS Date parse

热门文章

  1. iOS开发:一个瀑布流的设计与实现(已实现缓存池功能,该功能使得瀑布流cell可以循环利用)
  2. JavaScript高级 面向对象(13)--构造函数的执行过程
  3. openh264 api 使用
  4. jquery 回车事件实现代码
  5. R语言 ggplot2 画平滑图
  6. charles系列破解激活办法(最高charles4.2.5都可以激活,亲测可用)
  7. C++中,int a = 10的后面的操作
  8. 【AndroidManifest.xml详解】Manifest属性之sharedUserId、sharedUserLabel
  9. HashMap的最大容量为什么是2的30次方?
  10. php时间段判断