Groovy - 计数与集合中的where子句不同

时间:2014-02-06 16:18:53

标签: groovy

我有以下POJO课程:

public class MemberError{
    int lineNumber
    String type        // Can be 'A' or 'B'
    String message
}

同一成员可能有很多错误(相同的行号和类型,不同的消息)。

给定一个MemberError对象的集合,我希望找到类型A和B的不同成员(我的意思是lineNumber)的数量。

我到目前为止的解决方案是:

NoNullHashSet<Integer> typeAMems = errorSet.collect{ MemberError memErr ->
    if(memErr.type == 'A'){
        return memErr.lineNumber
    }
}
NoNullHashSet<Integer> typeBMems = errorSet.collect{ MemberError memErr ->
    if(memErr.type == 'B'){
        return memErr.lineNumber
    }
}
def numberOfTypeAMembersWithErrors = typeAMems.size()
def numberOfTypeBMembersWithErrors = typeBMems.size()

这似乎是正确的,但感觉不是很整洁。

有人可以建议使用Groovy集合API实现此目的的其他方法吗?

3 个答案:

答案 0 :(得分:3)

你不能这样做:

Set typeAMems = errorSet.findAll { it.type == 'A' }.lineNumber
Set typeBMems = errorSet.findAll { it.type == 'B' }.lineNumber

答案 1 :(得分:2)

您也可以使用groupBy

  

将所有集合成员排序为由(由)确定的(子)组   提供了映射闭包。

示例:

def l = [new MemberError(lineNumber: 10, type: 'A', message: 'Foo'), new MemberError(lineNumber: 20, type: 'B', message: 'Bar')]

def errorsByType = l.groupBy {
    it.type
}

errorsByType.'A'.lineNumber
errorsByType.'B'.lineNumber

Groovy控制台:

http://groovyconsole.appspot.com/script/2195001

答案 2 :(得分:1)

由于问题涉及最终计数而不是中间数据结构,因此请考虑使用具有默认值的嵌套映射:

// setup errorSet

class MemberError {
    int lineNumber
    String type        // Can be 'A' or 'B'
    String message
}

def errorSet = []
errorSet << new MemberError(lineNumber: 1, type: 'A', message: 'x')
errorSet << new MemberError(lineNumber: 1, type: 'A', message: 'y')
errorSet << new MemberError(lineNumber: 1, type: 'A', message: 'z')
errorSet << new MemberError(lineNumber: 2, type: 'A', message: 'a')
errorSet << new MemberError(lineNumber: 2, type: 'B', message: 'b')
errorSet << new MemberError(lineNumber: 2, type: 'B', message: 'c')

// simply count

def countMap = [:].withDefault { type -> 
    [:].withDefault { lineNumber -> 0 } 
}

errorSet.each { memberError ->
    countMap[memberError.type][memberError.lineNumber]++
}

// print results

countMap.each { type, map ->
    map.each { lineNumber, count ->
        println "count for { type: ${type} line: ${lineNumber} } = ${count}"
    }
}