我想将地图拆分成一组地图。例如,如果存在具有25个键/值对的映射。我想要一个地图数组,每个地图中的元素不超过10个。
我如何在groovy中做到这一点?
我有一个我不感兴趣的解决方案,是否有更好的groovy版本:
static def splitMap(m, count){
if (!m) return
def keys = m.keySet().toList()
def result = []
def num = Math.ceil(m?.size() / count)
(1..num).each {
def min = (it - 1) * count
def max = it * count > keys.size() ? keys.size() - 1 : it * count - 1
result[it - 1] = [:]
keys[min..max].each {k ->
result[it - 1][k] = m[k]
}
}
result
}
m是地图。 Count是地图中元素的最大数量。
答案 0 :(得分:6)
Adapting my answer to this question on partitioning a List,我想出了这个方法:
Map.metaClass.partition = { size ->
def rslt = delegate.inject( [ [:] ] ) { ret, elem ->
( ret.last() << elem ).size() >= size ? ret << [:] : ret
}
rslt.last() ? rslt : rslt[ 0..-2 ]
}
所以如果你拍这张地图:
def origMap = [1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f']
以下所有断言均通过: - )
assert [ [1:'a'], [2:'b'], [3:'c'], [4:'d'], [5:'e'], [6:'f'] ] == origMap.partition( 1 )
assert [ [1:'a', 2:'b'], [3:'c', 4:'d'], [5:'e', 6:'f'] ] == origMap.partition( 2 )
assert [ [1:'a', 2:'b', 3:'c'], [4:'d', 5:'e', 6:'f'] ] == origMap.partition( 3 )
assert [ [1:'a', 2:'b', 3:'c', 4:'d'], [5:'e', 6:'f'] ] == origMap.partition( 4 )
assert [ [1:'a', 2:'b', 3:'c', 4:'d', 5:'e'], [6:'f'] ] == origMap.partition( 5 )
assert [ [1:'a', 2:'b', 3:'c', 4:'d', 5:'e', 6:'f'] ] == origMap.partition( 6 )
或者,作为Category
(以避免向metaClass
的{{1}}添加任何内容:
Map
然后,在您需要此功能的地方,您可以简单地class MapPartition {
static List partition( Map delegate, int size ) {
def rslt = delegate.inject( [ [:] ] ) { ret, elem ->
( ret.last() << elem ).size() >= size ? ret << [:] : ret
}
rslt.last() ? rslt : rslt[ 0..-2 ]
}
}
类别:
use