如何使用groovy合并LinkedHashMaps的2个ArrayLists

时间:2017-08-30 12:32:55

标签: groovy

需要一些帮助,根据几个键合并2个LinkedHashMaps的ArrayLists。

这是数据的样子:

​def searchResults = [ 
  [dId:"prod_000001", groupName:"Group 1", subjectName:"Subject 1", dTitle:"Title 1"],
  [dId:"prod_000002", groupName:"Group 1", subjectName:"Subject 1", dTitle:"Title 2"],
  [dId:"prod_000003", groupName:"Group 1", subjectName:"Subject 2", dTitle:"Title 3"],
  [dId:"prod_000004", groupName:"Group 2", subjectName:"Subject 1", dTitle:"Title 4"]
]

def groupInfo = [ 
  [groupName:"Group 1", groupId:"01", subjectName:"Subject 1", subjectSortOrder:"01"],
  [groupName:"Group 1", groupId:"01", subjectName:"Subject 2", subjectSortOrder:"02"],
  [groupName:"Group 1", groupId:"01", subjectName:"Subject 3", subjectSortOrder:"03"],
  [groupName:"Group 2", groupId:"02", subjectName:"Subject 1", subjectSortOrder:"01"] 
]

我需要将groupInfo中的属性与基于groupName和subjectName的searchResults合并,如:

def mergedResults = mergeResults(searchResults,groupInfo,["groupName","subjectName"])

哪会导致:

mergedResult = [
  [dId:"prod_000001", groupName:"Group 1", subjectName: "Subject 1", dTitle: "Title 1", groupID:"01", subjectSortOrder:"01"],
  [dId:"prod_000002", groupName:"Group 1", subjectName: "Subject 1", dTitle: "Title 2", groupID:"01", subjectSortOrder:"01"],
  [dId:"prod_000003", groupName:"Group 1", subjectName: "Subject 2", dTitle: "Title 3", groupID:"01", subjectSortOrder:"02"],
  [dId:"prod_000004", groupName:"Group 2", subjectName: "Subject 1", dTitle: "Title 4", groupID:"02", subjectSortOrder:"01"]
]

2 个答案:

答案 0 :(得分:1)

以下一行是这样做的:

def mergedResults = searchResults.collect { searchResult ->
    searchResult + groupInfo.find {
        it.groupName == searchResult.groupName &&
        it.subjectName == searchResult.subjectName
    }
}

这是第二种选择:

def mergedResults = [searchResults, groupInfo]
    .combinations()
    .findAll {
        x, y -> x.groupName == y.groupName &&
                x.subjectName == y.subjectName
    }
    .collect { it.sum() }

构建查找地图的第三个变体:

def keyFn = { it.subMap 'groupName', 'subjectName' } 
groupInfo = groupInfo.collectEntries { [keyFn(it), it] }
def mergedResults = searchResults.collect { it + (groupInfo[keyFn(it)] ?: [:]) }

答案 1 :(得分:0)

为了加快查询速度,我在groupBygroupInfosubMap(["groupName", "subjectName"])首先。然后迭代searchResults, 查看groupInfo中是否有条目并将它们全部合并。

def keyFn = { it.subMap(["groupName", "subjectName"]) } 

def searchResults = [ 
    [dId:"prod_000001", groupName:"Group 1", subjectName:"Subject 1", dTitle:"Title 1"],
    [dId:"prod_000002", groupName:"Group 1", subjectName:"Subject 1", dTitle:"Title 2"],
    [dId:"prod_000003", groupName:"Group 1", subjectName:"Subject 2", dTitle:"Title 3"],
    [dId:"prod_000004", groupName:"Group 2", subjectName:"Subject 1", dTitle:"Title 4"]
]

def groupInfo = [ 
    [groupName:"Group 1", groupId:"01", subjectName:"Subject 1", subjectSortOrder:"01"],
    [groupName:"Group 1", groupId:"01", subjectName:"Subject 2", subjectSortOrder:"02"],
    [groupName:"Group 1", groupId:"01", subjectName:"Subject 3", subjectSortOrder:"03"],
    [groupName:"Group 2", groupId:"02", subjectName:"Subject 1", subjectSortOrder:"01"] 
].groupBy(keyFn) // XXX note the groupBy

// merge all search results by groupname/subjectName keys into each searchResult
def mergedResult = searchResults.collect{
    (groupInfo[keyFn(it)]?:[]).inject(it){ a,b -> a+b }
}

assert mergedResult == [
    [dId:"prod_000001", groupName:"Group 1", subjectName: "Subject 1", dTitle: "Title 1", groupId:"01", subjectSortOrder:"01"],
    [dId:"prod_000002", groupName:"Group 1", subjectName: "Subject 1", dTitle: "Title 2", groupId:"01", subjectSortOrder:"01"],
    [dId:"prod_000003", groupName:"Group 1", subjectName: "Subject 2", dTitle: "Title 3", groupId:"01", subjectSortOrder:"02"],
    [dId:"prod_000004", groupName:"Group 2", subjectName: "Subject 1", dTitle: "Title 4", groupId:"02", subjectSortOrder:"01"]
]