2

私は PHP の世界から来て、レコードの集計を行う必要があります。PHPではこれは簡単ですが、Groovyで次のことを行うにはどうすればよいですか

$logs = array( array( 'date' => '5-15', 'name' => 'foo' ...other stuff),
               array( 'date' => '5-15', 'name' => 'bar' ...other stuff),
               array( 'date' => '5-16', 'name' => 'foo' ...other stuff),
               array( 'date' => '5-17', 'name' => 'foo' ...other stuff),
               array( 'date' => '5-17', 'name' => 'foo' ...other stuff),
               array( 'date' => '5-17', 'name' => 'bar' ...other stuff),
               array( 'date' => '5-17', 'name' => 'bar' ...other stuff) );

$counts = array();

foreach($logs as $log) {
   if( isset($counts[ $log['date'] ][ $log['name'] ]) ) {
       $counts[ $log['date'] ][ $log['name'] ] = 1;
   } else {
       $counts[ $log['date'] ][ $log['name'] ]++;
   }
}

結果が得られます

['5-15']['foo'] = 1
['5-15']['bar'] = 1
['5-16']['foo'] = 1
['5-17']['foo'] = 2
['5-17']['bar'] = 2

ログは、実際には GORM クエリから返された結果セットです。

4

2 に答える 2

4

Groovy countByを使用できます。

def map = logs.countBy{[it.date, it.name]}

結果のマップと対応するカウントが得られます。あなたの場合、それは次のようになります

[[5-15, foo]:1, [5-15, bar]:1, [5-16, foo]:1, [5-17, foo]:2, [5-17, bar]:2]

サンプル

def logs = [
        [ date: '5-15', name: 'foo'],
        [ date: '5-15', name: 'bar'],
        [ date: '5-16', name: 'foo'],
        [ date: '5-17', name: 'foo'],
        [ date: '5-17', name: 'foo'],
        [ date: '5-17', name: 'bar'],
        [ date: '5-17', name: 'bar']]

def map = logs.countBy{[it.date, it.name]}

assert map[['5-15', 'foo']] == 1
assert map[['5-15', 'bar']] == 1
assert map[['5-16', 'foo']] == 1
assert map[['5-17', 'foo']] == 2
assert map[['5-17', 'bar']] == 2

マップからペアを取得eachする必要がある場合。<key,value>あなたは非常によく次のようにすることができます:-

map.each{k, v ->
    println "$k has been used $v times"
}

//Prints:
[5-15, foo] has been used 1 times
[5-15, bar] has been used 1 times
[5-16, foo] has been used 1 times
[5-17, foo] has been used 2 times
[5-17, bar] has been used 2 times

Groovy 2.1.3 でテスト済み

于 2013-05-31T20:03:37.140 に答える
2

これは、カウント マップで複合キーを使用しています。ただし、他の方法でスライスしてさいの目に切ることもできます。

def logs = [
        [ date: '5-15', name: 'foo'],
        [ date: '5-15', name: 'bar'],
        [ date: '5-16', name: 'foo'],
        [ date: '5-17', name: 'foo'],
        [ date: '5-17', name: 'foo'],
        [ date: '5-17', name: 'bar'],
        [ date: '5-17', name: 'bar']]

def counts = [:]         
logs.collectEntries(counts) { 
    def key = [it.date, it.name]
    def count = counts[key] ?: 0
    [key, count + 1]
}


assert counts[['5-15', 'foo']] == 1
assert counts[['5-15', 'bar']] == 1
assert counts[['5-16', 'foo']] == 1
assert counts[['5-17', 'foo']] == 2
assert counts[['5-17', 'bar']] == 2
于 2013-05-31T20:03:20.437 に答える