使用Groovy拆分地图

时间:2011-01-06 20:59:13

标签: grails groovy

我想将地图拆分成一组地图。例如,如果存在具有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是地图中元素的最大数量。

1 个答案:

答案 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