Groovy 关闭查找相似用户记录
Groovy closure to find similar user records
我的 LawfirmUser 实体具有 FirstName
、LastName
和 userId
属性,下面是 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}"
}
}
我的 LawfirmUser 实体具有 FirstName
、LastName
和 userId
属性,下面是 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}"
}
}