使用Groovy或Java比较两个映射并找出差异 [英] Compare two maps and find differences using Groovy or Java
问题描述
我想在两张地图上找到差异,并创建一个新的csv文件,其中包含以下差异(并将差异放在**之间):
地图1
[
[cuInfo:T12,service:3,startDate:14-01-16 1322,appId:G12355],
[cuInfo:T13,service:3,startDate:12-02-16 13:00,appId:G12356],
[cuInfo:T14,服务:9,startDate:10-01-16 11:20,appId:G12300],
[cuInfo:T15,service: 10,startDate:26-02-16 10:20,appId:G12999]
]
地图2
[
[name:Apple,cuInfo:T12, service:3,startDate:14-02-16 10:00,appId:G12351],
[name:Apple,cuInfo:T13,service:3,startDate :14-01-16 13:00,appId:G12352],
[名称:Apple,cuInfo:T16,服务:3,startDate:14-01-16 13:00,appId:G12353],
[name:Google,cuInfo:T14,service:9,startDate:10-01-16 11:20,appId: G12301],
[名称:Microsoft,cuInfo:T15 ,service:10,startDate:26-02-16 10:20,appId:G12999],
[name:Microsoft,cuInfo:T18,service:10 ,startDate:26-02-16 10:20,appId:G12999]
]
我怎样才能得到如下所示的输出csv?
Map 1 data |地图2数据
服务3;名称Apple;
cuInfo; startDate; appId | cuInfo; startDate; appId
T12; * 14-02-16 10:00 *; * G12351 * | T12; * 14-01-16 13:22 *; * G12355 *
T13; * 14-01-16 13:00 *; * G12352 * | T13; * 12-02-16 13:00 *; * G12356 *
服务9;名称为Google;
T14; * 10-01-16 11:20 *; * G12301 * | T12; * 10-01-16 11:20 *; * G12300 *
谢谢
在下面的例子中,我假设地图列表被适当地排序,以便比较公平,并且这两个列表都是相同的长度:
首先,创建一个 Iterator
来同时遍历两个列表:
@ groovy.transform.TupleConstructor
class DualIterator实现Iterator< List> {
Iterator iter1
Iterator iter2
布尔hasNext(){
iter1.hasNext()&& iter2.hasNext()
}
列表next(){
[iter1.next(),iter2.next()]
}
void remove(){
throw new UnsupportedOperationException()
}
}
接下来,处理列表以获取CSV文件的行:
def rows = new DualIterator(list1 .iterator(),list2.iterator())
pre>
.findAll {it [0]!= it [1]} //获取不匹配的行。
.collect {//标记不匹配的值。
(m1,m2)= it
m1.keySet()。each {key - >
if(m1 [key]!= m2 [key]){
m1 [key] =* $ {m1 [key]} *
m2 [key] =* $ {m2 [key]} *
}
}
[m1,m2]
} .collect {//将地图值合并到字符串列表中数组
[it [0] .values(),it [1] .values()]。flatten()as String []
}
最后,以CSV格式写出标题和行。注意:我使用的是正确的CSV;您的示例实际上是无效,因为列数不一致:
def writer = new CSVWriter新的FileWriter('blah.csv'))
writer.writeNext(['name1','cuInfo1','service1','startDate1','appId1','name2','cuInfo2','service2' ,'startDate2','appId2'] as String [])
writer.writeAll(rows)
writer.close()
输出如下所示:
name1,cuInfo1, service1,startDate1,appId1,name2,cuInfo2,service2,startDate2,appId2
Apple,T12,3,* 14 -02-16 10:00 *,* G12351 *,Apple,T12,3,* 14-01-16 13:22 *,* G12355 *
Apple,T13,3,* 14-01-16 13:00 *,* G12352 *,Apple,T13,3,* 12-02-16 13:00 *,* G12356 *,
Google,T14,9,10-01-16 11:20,* G12301 *,Google,T14 ,9,10-01-16 11:20,* G12300 *
I would like to find difference in two maps and create a new csv file with the difference (and put the difference between **) like below:
Map 1
[ [cuInfo:"T12",service:"3",startDate:"14-01-16 13:22",appId:"G12355"], [cuInfo:"T13",service:"3",startDate:"12-02-16 13:00",appId:"G12356"], [cuInfo:"T14",service:"9",startDate:"10-01-16 11:20",appId:"G12300"], [cuInfo:"T15",service:"10",startDate:"26-02-16 10:20",appId:"G12999"] ]
Map 2
[ [name:"Apple", cuInfo:"T12",service:"3",startDate:"14-02-16 10:00",appId:"G12351"], [name:"Apple",cuInfo:"T13",service:"3",startDate:"14-01-16 13:00",appId:"G12352"], [name:"Apple",cuInfo:"T16",service:"3",startDate:"14-01-16 13:00",appId:"G12353"], [name:"Google",cuInfo:"T14",service:"9",startDate:"10-01-16 11:20",appId:"G12301"], [name:"Microsoft",cuInfo:"T15",service:"10",startDate:"26-02-16 10:20",appId:"G12999"], [name:"Microsoft",cuInfo:"T18",service:"10",startDate:"26-02-16 10:20",appId:"G12999"] ]
How can I get the output csv like below
Map 1 data | Map 2 data service 3;name Apple; cuInfo;startDate;appId | cuInfo;startDate;appId T12;*14-02-16 10:00*;*G12351* | T12;*14-01-16 13:22*;*G12355* T13;*14-01-16 13:00*;*G12352* | T13;*12-02-16 13:00*;*G12356* service 9;name Google; T14;*10-01-16 11:20*;*G12301* | T12;*10-01-16 11:20*;*G12300*
Thanks
解决方案In the following I'm assuming that the list of maps is sorted appropriately so that the comparison is fair, and that both lists are of the same length:
First, create an
Iterator
to traverse both lists simultaneously:@groovy.transform.TupleConstructor class DualIterator implements Iterator<List> { Iterator iter1 Iterator iter2 boolean hasNext() { iter1.hasNext() && iter2.hasNext() } List next() { [iter1.next(), iter2.next()] } void remove() { throw new UnsupportedOperationException() } }
Next, process the lists to get rows for the CSV file:
def rows = new DualIterator(list1.iterator(), list2.iterator()) .findAll { it[0] != it[1] } // Grab the non-matching lines. .collect { // Mark the non-matching values. (m1, m2) = it m1.keySet().each { key -> if(m1[key] != m2[key]) { m1[key] = "*${m1[key]}*" m2[key] = "*${m2[key]}*" } } [m1, m2] }.collect { // Merge the map values into a List of String arrays [it[0].values(), it[1].values()].flatten() as String[] }
Finally, write the header and rows out in CSV format. NOTE: I'm using a proper CSV; your example is actually invalid because the number of columns are inconsistent:
def writer = new CSVWriter(new FileWriter('blah.csv')) writer.writeNext(['name1', 'cuInfo1', 'service1', 'startDate1', 'appId1', 'name2', 'cuInfo2', 'service2', 'startDate2', 'appId2'] as String[]) writer.writeAll(rows) writer.close()
The output looks like this:
"name1","cuInfo1","service1","startDate1","appId1","name2","cuInfo2","service2","startDate2","appId2" "Apple","T12","3","*14-02-16 10:00*","*G12351*","Apple","T12","3","*14-01-16 13:22*","*G12355*" "Apple","T13","3","*14-01-16 13:00*","*G12352*","Apple","T13","3","*12-02-16 13:00*","*G12356*" "Google","T14","9","10-01-16 11:20","*G12301*","Google","T14","9","10-01-16 11:20","*G12300*"
这篇关于使用Groovy或Java比较两个映射并找出差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!