我有一个带有街道地址,邮政编码,国家,省份等的列表。
我想将同一条街道的所有门牌号重新分组,如下所示:
City Street Cp Housenumber etc......
Qc Rue Prudent-Cloutier G0E 1V0 1-3,6,9-11
Qc Rue Godin G0E 1V0 102-104
.
.
.
.所以我所做的是获取街道列的所有唯一值,并将它们添加到一个新列表中,并将其与第一个列表中的所有值进行比较,但我总是得到空值……
def str ='''\
'''
def xml = new XmlParser().parseText(str)
List newAddressList=new ArrayList();
List StreetsAdress=new ArrayList();
List newUniqueList=new ArrayList();
def iter_String = xml.Rows[0].@Items
int iter = new Integer(iter_String).intValue()
z=0
for (int i=0; i < iter ; i++){
LastId = xml.Rows[0].Row[i].@Id
def (Country, Type) = LastId.tokenize( '\\|' )
Text = xml.Rows[0].Row[i].@Text
def (HouseNumber, Street) = Text.split(" " ,2)
if (HouseNumber!="CP"){
Description = xml.Rows[0].Row[i].@Description
def (City,City_ab,Code_postale ) = Description.tokenize( ',' )
newAddressList.add(['RecordId1':z++,'Country1 ':Country,'HouseNumber1':HouseNumber,'Street1': Street,'City1':City,'City_ab1':City_ab,'Code_postale1':Code_postale]);
StreetsAdress.add(['StreetList':Street]);
newUniqueList = StreetsAdress.unique();
}
}
println newUniqueList所以我想知道如何比较newUniqueList(只包含街道,没有重复)和newAddressList (包含所有信息),并对所有houseNumbers进行重组。感谢您的帮助!
发布于 2021-02-25 02:30:48
以下代码:
import groovy.xml.*
def data = '''
'''
def xml = new XmlSlurper().parseText(data)
def collapsed = xml.Rows.Row.groupBy { row ->
def matcher = row.@Text =~ /[^0-9]+/
matcher[0]
}.collect { street, rows ->
def nums = rows.collect { row ->
row.@Text.text().tokenize(' ').first() as Integer
}.sort()
def tokens = rows.first().@Description.text().tokenize(',')
def range = nums.size() == 1 ? "${nums.first()}" : "${nums.first()}-${nums.last()}"
[City: tokens[1].trim(), Street: street.trim(), Cp: tokens[2].trim(), HouseNumber: range]
}
def headers = ['City', 'Street', 'Cp', 'HouseNumber']
def widths = headers.collectEntries { header ->
[header, collapsed.collect { it[header].length() }.max() + 4]
}
headers.each { header ->
print(header.padRight(widths[header]))
}
println()
collapsed.each { row ->
headers.each { header ->
print(row[header].padRight(widths[header]))
}
println()
}运行时,打印:
─➤ groovy solution.groovy
City Street Cp HouseNumber
QC Rue Prudent-Cloutier G0E 1V0 1-11
QC Rte Rue Prudent-Cloutier G0E 1V0 9
QC Rue Municipale G0E 1V0 102
QC Rue Godin G0E 1V0 102-104...went额外的一步,并对输出进行了一些格式化,这会使解决方案变得复杂,但这应该会为您提供一个如何使用它的示例。
由于这有点复杂,我将为代码的主要部分添加一些解释。
解释:
xml.Rows.Row.groupBy { row ->
def matcher = row.@Text =~ /[^0-9]+/
matcher[0]
}返回的行列表。xml.Rows.Row并将它们分组到Row.Text的非数字部分(即不带数字的街道名称,例如:"Rue Prudent-Cloutier")。groupBy返回一个Map换句话说,这些行是按地址所在的街道分组的(不包括数字)。
.collect { street, rows ->
...
}这将遍历Map>并创建一个列表。换句话说,对于每条街道,这个闭包({ })将使用街道名称("Rue Prudent-Cloutier")调用一次,并调用在“Rue Prudent-Cloutier”中具有该街道名称的所有行。rows列表。collect将返回一个List在哪里something是这个闭包返回的内容。
def nums = rows.collect { row ->
row.@Text.text().tokenize(' ').first() as Integer
}.sort()获取特定街道的所有行,例如"Rue Prudent-Cloutier",提取街道编号(1、3等),将它们转换为整数并进行排序,然后nums是一个List最先是最小的数字,最后是最大的数字。
def tokens = rows.first().@Description.text().tokenize(',')拆分说明文本,如下所示Mont-Saint-Pierre, QC, G0E 1V0在逗号返回时List(在本例中为`‘圣皮尔山’,'QC','G0E 1V0‘)。
def range = nums.size() == 1 ? "${nums.first()}" : "${nums.first()}-${nums.last()}"获取排序后的门牌号,然后创建一个单个数字字符串9或范围字符串1-11并将其存储在变量中range。
[City: tokens[1].trim(), Street: street.trim(), Cp: tokens[2].trim(), HouseNumber: range]这最终创建了来自.collect { street, rows -> ... }。这是groovy的map语法,换句话说,collect中的每个迭代都将返回一个map和collapsed将因此具有类型List>,或者用一个更简单的例子,collapsed会有这样的结构:
[[City: QC, Street: Rue Prudent-Cloutier, Cp: G0E 1V0, HouseNumber:1-11],
[City: QC, Street: Rue Municipale, Cp: G0E 1V0, HouseNumber:102]
...
]至于你应该把你的条件放在哪里,我认为你必须根据你的需要进行修改。
https://stackoverflow.com/questions/66341218
复制相似问题