我的map
结构如下: -
def map = [107:[[107, "Module 01", 1], [107, "Module New", 6]], 109:[[109, "Module 04", 1]]]
我们有一项任务要将此map
表示为以下结构: -
Application | Module 01 | Module New | Module 04
107 | 1 | 6 | 0
109 | 0 | 0 | 1
因此,对于此表示,我想过滤map
,如下所示: -
def outputMap = [moduleList:["Module 01", "Module New", "Module 04"], dataList:[[107:[1, 6, 0]], [109:[0, 0, 1]]]]
为了达到这个目的,我做了如下: -
def getFilteredMap(Map map) {
def moduleList = map.findResults {
it.value.findResults { it[1] }
}.flatten()
def dataList = []
map*.key.each { app ->
def tempMap = [:]
tempMap[app] = map.findResults {
it.value.findResults {
(it[0] == app) ? it[2] : 0
}
}.flatten()
dataList << tempMap
}
return ["moduleList" : moduleList, "dataList" : dataList]
}
def map = [107:[[107, "Module 01", 1], [107, "Module New", 6]], 109:[[109, "Module 04", 1]]]
def outputMap = [moduleList:["Module 01", "Module New", "Module 04"], dataList:[[107:[1, 6, 0]], [109:[0, 0, 1]]]]
assert outputMap == getFilteredMap(map)
但是你可以看到getFilteredMap()
方法过滤地图,因为欲望输出不是很好。
注意: - 此处可能会重复模块名称,但我只想要唯一的模块名称列表表示为Set
。
有人可以提出更好的方法来实现这个目标吗?
答案 0 :(得分:2)
考虑将公共代码提取到新方法中。
(编辑:我还使用了collect
和collectEntries
来清理dataList
部分,正如RudolphEst所建议的那样)
def findAsFlat(map, f) {
map.findResults { it.value.findResults(f) }.flatten()
}
def getFilteredMap(Map map) {
def moduleList = findAsFlat(map, { it[1] })
def dataList = map*.key.collect { app ->
map.collectEntries ([:]) {
[app, findAsFlat(map, {(it[0] == app) ? it[2] : 0})]
}
}
return ["moduleList" : moduleList, "dataList" : dataList]
}
def map = [107:[[107, "Module 01", 1], [107, "Module New", 6]], 109:[[109, "Module 04", 1]]]
def outputMap = [moduleList:["Module 01", "Module New", "Module 04"], dataList:[[107:[1, 6, 0]], [109:[0, 0, 1]]]]
assert outputMap == getFilteredMap(map)
这比原版更清晰,便于单元测试。
答案 1 :(得分:1)
因为你的输入是在地图而不是一个漂亮的单位列表中,我建议的最佳计划是按照以下方式创建dataList
(collect
而不是附加[{{1}进入它)
<<
我可能还建议您使用 def dataList = map*.key.collect { app ->
[(app) : map.findResults {
it.value.findResults {
(it[0] == app) ? it[2] : 0
}
}.flatten()]
}
并将collectEntries
改为地图。
答案 2 :(得分:1)
这就是我得到的:
def transformMap( map ) {
// 1st collect all names to be used as 0-filled "grid-pattern"
def moduleList = map.values().inject( [] ){ res, curr ->
for( v in curr ) res << v[ 1 ]
res
}.unique()
// now fill the dataList, positioning the values according to the grid
def dataList = map.inject( [:].withDefault{ [0] * moduleList.size() } ){ res, curr ->
for( v in curr.value ) res[ curr.key ][ moduleList.indexOf( v[ 1 ] ) ] = v[ 2 ]
res
}.inject( [] ){ res, curr ->
res << [( curr.key ): curr.value]
res
}
[moduleList: moduleList, dataList: dataList]
}
def m = [107: [[107, "Module 01", 1], [107, "Module New", 6]], 109: [[109, "Module 04", 1]]]
def expected = [moduleList:["Module 01", "Module New", "Module 04"], dataList:[[107:[1, 6, 0]], [109:[0, 0, 1]]]]
assert expected == transformMap( m )