Go语言如何比较[]RecordProxy与[]RecordSource结构体切片是否相等
首先给出两个结构体定义:
type RecordProxy struct { Amt int `csv:"Amt"` Descr string `csv:"Descr"` Date string `csv:"Date"` ID string `csv:"ID"` } type RecordSource struct { Date string `csv:"Date"` ID string `csv:"ID"` Amount int `csv:"Amount"` Description string `csv:"Description"` }
两个结构体的字段映射关系为:
RecordProxy.Amt对应RecordSource.AmountRecordProxy.Descr对应RecordSource.DescriptionRecordProxy.Date对应RecordSource.DateRecordProxy.ID对应RecordSource.ID
要判断[]RecordProxy和[]RecordSource内容是否相等,首先做前置判断:如果两个切片长度不相等,直接判定为内容不相等,再根据是否要求元素顺序一致选择对应方案:
方案1:要求元素顺序完全对应相等
直接逐索引遍历比较对应字段即可,性能最高,逻辑无歧义:
func SlicesOrderEqual(proxies []RecordProxy, sources []RecordSource) bool { if len(proxies) != len(sources) { return false } for i := range proxies { p, s := proxies[i], sources[i] if p.Amt != s.Amount || p.Descr != s.Description || p.Date != s.Date || p.ID != s.ID { return false } } return true }
方案2:不要求元素顺序,仅要求元素集合完全匹配
一般以ID作为唯一标识,先把其中一类切片转为ID为键的map,再遍历另一类切片做匹配:
func SlicesCollectionEqual(proxies []RecordProxy, sources []RecordSource) bool { if len(proxies) != len(sources) { return false } // 把source切片转为ID为键的map sourceMap := make(map[string]RecordSource, len(sources)) for _, s := range sources { // 如果存在重复ID,可根据业务需求调整处理逻辑,比如直接返回false if _, ok := sourceMap[s.ID]; ok { return false } sourceMap[s.ID] = s } // 遍历proxy切片匹配 for _, p := range proxies { s, ok := sourceMap[p.ID] if !ok { return false } if p.Amt != s.Amount || p.Descr != s.Description || p.Date != s.Date { return false } // 匹配成功后删除键,避免source有多余元素 delete(sourceMap, p.ID) } // 最终map为空则完全匹配 return len(sourceMap) == 0 }
通用扩展方案
如果后续有大量类似结构体需要比较,可以通过反射解析csv标签自动匹配字段,无需手动编写字段比较逻辑,缺点是性能略低于手动实现的代码。
内容的提问来源于stack exchange,提问作者Calvin
相关产品推荐
相关产品推荐

