Groovy 关闭查找相似用户记录

Groovy closure to find similar user records

我的 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 和闭包方面的新手,有人可以帮我解决闭包问题吗?

不幸的是不知道输入来自哪里,但这是如何完成的(从字符串解析的输入)- 请参阅评论以进行澄清。有问题欢迎随时提问

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

我在这里完成了一个示例: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}"
    }
}