Groovy闭包找到类似的用户记录

时间:2015-01-02 17:48:45

标签: groovy closures

我的LawfirmUser实体包含FirstNameLastNameuserId以下属性是LawfirmUser的一些示例数据

FirstName      LastName     userId
----------   -----------  ----------
Demo            test1         1
Demo            test1         2
Demo            test1         3
Demo            test2         4
Demo            test2         5
Demo            test3         6 
Demo            test4         7 

我有一个groovy列表lawfirmUsersList(LawfirmUsers)并且我正在尝试编写一个闭包来查找所有具有相同名字和姓氏但不同userIds的记录

关闭应打印在数据下面

FirstName      LastName     userId
----------   -----------  ----------
Demo            test1         1
Demo            test1         2
Demo            test1         3
Demo            test2         4
Demo            test2         5

我非常喜欢Groovy和关闭的东西,有人可以帮我关闭一下吗?

2 个答案:

答案 0 :(得分:1)

不幸的是,不知道输入的来源,但是这里是如何完成的(输入从字符串解析) - 请参阅注释以便澄清。如有任何问题,请随时询问。

def input ="""FirstName      LastName     userId
----------   -----------  ----------
Demo            test1         1
Demo            test1         2
Demo            test1         3
Demo            test2         4
Demo            test2         5
Demo            test3         6 
Demo            test4         7"""

input.split('\n')[2..-1] // split input with '\n' and ignore the first two lines
.collect { //transform each line to an instance of Map
    def splitted = it.split()
    [firstName: splitted[0], lastName: splitted[1], userId: splitted[2]]
}
.groupBy { //group maps by pair 'firstNamelastName' - here same firstnames and lastnames are found
    it.firstName + it.lastName 
}
.values() //take values for keys
.findAll { //ignore single entries e.g. 'Demotest4'
    it.size() > 1 
}.flatten() // remove list nesting
.each { println it} //print found lines

null

更新(评论后)

import groovy.transform.ToString

def input ="""Demo            test1         1
Demo            test1         2
Demo            test1         3
Demo            test2         4
Demo            test2         5
Demo            test3         6 
Demo            test4         7"""

@ToString
class LawfirmUser {
    String firstName
    String lastName
    Integer userId
}

def users = input.split('\n').collect {
    def splitted = it.split()
    new LawfirmUser(firstName: splitted[0], lastName: splitted[1], userId: splitted[2].toInteger())
}

def filtered = users.groupBy { it.firstName + it.lastName }.values().findAll { it.size() > 1 }.flatten()
assert filtered.size() == 5
filtered.each {
    println it
}

null

答案 1 :(得分:0)

我在这里做了一个例子:https://groovyconsole.appspot.com/script/5745580152193024

我认为它回答了你的问题的核心,即如何使用闭包和Groovy对集合API的功能扩展来操纵数据。这是一个可以通过多种方式解决的问题,希望我能帮助您深入了解惯用的groovy集合是如何工作的。

代码内联供参考:

//your raw data as groovy maps, which will behave like objects
def lawFirms=[
    [firstName:"Demo",lastName:"test1",userId:1],
    [firstName:"Demo",lastName:"test1",userId:2],
    [firstName:"Demo",lastName:"test1",userId:3],
    [firstName:"Demo",lastName:"test2",userId:4],
    [firstName:"Demo",lastName:"test2",userId:5],
    [firstName:"Demo",lastName:"test3",userId:6],
    [firstName:"Demo",lastName:"test4",userId:7]
]
//get a cont of entries by lastname
def counts=lawFirms.countBy{ firm -> firm.lastName }   //[test1:3, test2:2, test3:1, test4:1]
//filter out only those with count > 1 i.e. not unique
def hasMoreThanOne = counts.findAll{ k,v -> v>1 }      //[test1:3, test2:2]
//construct a map with each lastname that has >1 entries as keys, and list of all matching firms as entry
//(not simplest for just printing, but seems like a good way to organise results in general)
def multipleGroups = hasMoreThanOne.collectEntries([:]){ k,v ->
    [k,lawFirms.findAll{ firm -> k==firm.lastName }]
}    /*[test1:[
            [firstName:Demo, lastName:test1, userId:1],
            [firstName:Demo, lastName:test1, userId:2],
            [firstName:Demo, lastName:test1, userId:3]
        ],
        test2:[
            [firstName:Demo, lastName:test2, userId:4],
            [firstName:Demo, lastName:test2, userId:5]
        ]
    ]*/

//iterate through data structure printing out results
multipleGroups.each{ k,v ->
    v.each{ firm ->
        println "${firm.firstName},${firm.lastName},${firm.userId}"
    }
}