我正在进行数据处理,一项任务是获取人员分布的统计数据。对于名为“john doe”的人来说,有不同的州,ca,ar和ny,以及不同年龄组,二十几岁,三十岁等等。{1,2}或{3}是人们的身份。
"john doe" => "ca:tw#2{1,2}:th#1{3};ar:tw#1{4}:fi#1{5};ny:tw#1{6};"
现在,如果我想在年龄为tw的情况下获得john doe的id,我应该如何获得它们?也许使用正则表达式?如果我想为它添加一个新的ID,比如说100,现在就变成了
"john doe" => "ca:tw#3{1,2,100}:th#1{3};ar:tw#1{4}:fi#1{5};ny:tw#1{6};"
我应该怎么做?
谢谢!
答案 0 :(得分:1)
在程序中使用字符串是没有意义的。您可以在存储时从字符串中读取数据,或者以这种方式将其写回,但是您应该以易于操作的方式存储它。例如:
data = {
"john doe" => {
"ca" => {
"tw" => [1,2],
"th" => [3]
},
"ar" => {
"tw" => [4],
"fi" => [5]
},
"ny" => {
"tw" => [6]
}
}
}
鉴于此,加州约翰·多伊在20多岁时的ids是data['john doe']['ca']['tw']
。这样的John Doe的数量是data['john doe']['ca']['tw'].length
;第一个ID是data['john doe']['ca']['tw'][0]
,第二个是data['john doe']['ca']['tw'][1]
。您可以使用data['john doe']['ca']['tw'] << 100
向其添加ID 100;那么100就是data['john doe']['ca']['tw'][2]
的值。
如果我写这篇文章,我可能会使用年龄范围键(20,30,50)的实际数字而不是那些模糊的字母前缀。
答案 1 :(得分:1)
如果你想坚持使用字符串操作,可以使用正则表达式和gsub。
这是一种方法。它可以使用一些清理(例如错误处理,重新分解等),但我认为它会让你开始。
def count(details, location, age_group)
location_details = /#{location}(.+?);/.match(details)[1]
age_count = /#{age_group}#(\d+)\{/.match(details)[1]
return age_count.to_i
end
def ids(details, location, age_group)
location_details = /#{location}(.+?);/.match(details)[1]
age_ids = /#{age_group}#\d+\{(.+?)\}/.match(details)[1]
return age_ids
end
def add(details, location, age_group, new_id)
location_details = /#{location}(.+?);/.match(details)[1]
new_count = count(details, location, age_group) + 1
new_ids = ids(details, location, age_group) + ',' + new_id
location_details.gsub!(/#{age_group}#\d+\{(.+?)\}/, "#{age_group}##{new_count}{#{new_ids}}")
details.gsub!(/#{location}(.+?);/, "#{location}#{location_details};")
end
你可以看到它产生你想要的结果(至少在功能上,不确定性能):
names = {"john doe" => "ca:tw#2{1,2}:th#1{3};ar:tw#1{4}:fi#1{5};ny:tw#1{6};"}
puts count(names["john doe"], 'ca', 'tw')
#=> 2
puts ids(names["john doe"], 'ca', 'tw')
#=> 1,2
names["john doe"] = add(names["john doe"], 'ca', 'tw', '100')
puts names["john doe"]
#=> ca:tw#3{1,2,100}:th#1{3};ar:tw#1{4}:fi#1{5};ny:tw#1{6};