Groovy扩展或展平分层嵌套映射

时间:2016-04-28 23:41:59

标签: groovy

我想将列表(..of lists)层次结构的嵌套列表扩展为表结构 注意:结构不固定,可能有多个级别。

一个简单的例子是:

[ mother:Mary,
  father:Bill,
  child:[
      [  name:Joe,
         gender:male,
         age:5,
         friend:[
                  name: Bob
                ]
      ],
      [  name:Jill,
         gender:female,
         age:12,
         friend:[ name:Lucy,
                   name:Peanuts
                 ]
      ]
   ]
   pet: dog
   living: together 
]

进入平面数据表:

| mother | father | child.Name | child.gender | child.age | child.friend.name | pet | living   |
| Mary   | Bill   | Joe        | male         | 5         | Bob               | dog | together |
| Mary   | Bill   | Jill       | female       | 12        | Lucy              | dog | together |
| Mary   | Bill   | Jill       | female       | 12        | Peanuts           | dog | together |

我可能在Lambda Calculus (约20年前)中做过类似的事情。
并且,我认为我需要通过结构进行递归并记录路径,也许? 任何帮助都会很好。 :)

我试过了:

Collection flat (Map m, String s='.'){
    m.collect{ k, v ->
        if (v instanceof Map){
            v.collectEntries{ p, q ->
                [(k+'.'+p):q]
            }
        }
        else if (v instanceof Collection){
            v.collect{ it.collectEntries{ p, q ->
                [(k+'.'+p):q]
            }}
        }
        else {
            [(k):v]
        }
    }
}

println "flat([a:1, b:2, c:3]) =" + flat([a:1, b:2, c:3])
assert [[a:1], [b:2], [c:3]] == flat([a:1, b:2, c:3])
println "flat([a:1, b:[x:1,y:2,z:3], c:3]) =" + flat([a:1, b:[x:1,y:2,z:3], c:3])
assert [[a:1], ['b.x':1, 'b.y':2, 'b.z':3], [c:3]] == flat([a:1, b:[x:1,y:2,z:3], c:3])
println "flat([a:1, b:[[x:1,y:2,z:3],[x:2,y:4,z:6]], c:3]) =" + flat([a:1, b:[[x:1,y:2,z:3],[x:2,y:4,z:6]], c:3])
assert [[a:1], [['b.x':1, 'b.y':2, 'b.z':3], ['b.x':2, 'b.y':4, 'b.z':6]], [c:3]] == flat([a:1, b:[[x:1,y:2,z:3],[x:2,y:4,z:6]], c:3])

(由Mathieu Carbou提供[http://blog.mathieu.carbou.me/post/103326044231/how-to-flatten-a-map-in-groovy]

Map flatten(Map m, String separator = '.') {
     m.collectEntries { k, v ->
         if (v instanceof Map){
             flatten(v, separator).collectEntries { q, r ->
                 [(k + separator + q): r]
             }
         }
         else {
             [(k):v]
         }
     }
}
println "flatten([a:[b:1, c:[d:2,e:3]]]) ="+flatten([a:[b:1, c:[d:2,e:3]]])
assert ['a.b':1, 'a.c.d':2, 'a.c.e':3] == flatten([a:[b:1, c:[d:2,e:3]]])
println "flatten([a:1, b:[x:1,y:2,z:3], c:[x:2,y:4,z:6], d:3]) ="+flatten([a:1, b:[x:2,y:3,z:4], c:[x:5,y:6,z:7], d:8])
assert [a:1, 'b.x':2, 'b.y':3, 'b.z':4, 'c.x':5, 'c.y':6, 'c.z':7, d:8] == flatten([a:1, b:[x:2,y:3,z:4], c:[x:5,y:6,z:7], d:8])
println ""
println "Goal is flatten([a:1, b:[x:2,y:3,z:4],[x:5,y:6,z:7], c:8]) = [[a,'b.x','b.y','b.z',c],[1,2,3,4,8],[1,5,6,7,8]]"
println ""
println "flatten([a:1, b:[[x:2,y:3,z:4],[x:5,y:6,z:7]], c:8]) ="+flatten([a:1, b:[[x:2,y:3,z:4],[x:5,y:6,z:7]], c:8])
// But, this doesn't deal with list elements or pull out the keys(headings)
// So gives me
assert [a:1, b:[[x:2, y:3, z:4], [x:5, y:6, z:7]], c:8] == flatten([a:1, b:[[x:2,y:3,z:4],[x:5,y:6,z:7]], c:8])

0 个答案:

没有答案