我有这一系列的城市:
footer
名称,州和州际公路数组是每个城市的属性。
我想通过州际公路对它们进行分组,以便最终结果看起来像这样:
Bakersfield, California
Interstates: ["I-5"]
Oakland, California
Interstates: ["I-80"]
Atlanta, Georgia
Interstates: ["I-20", "I-75", "I-86"]
Cleveland, Ohio
Interstates: ["I-71", "I-77", "I-80", "I-90"]
Arlington, Texas
Interstates: ["I-20", "I-30"]
有快速的方法吗?
编辑:这是真正的数组,就像@wurde一样。
I-20: [Arlington, Atlanta]
I-5: [Bakersfield]
I-86: [Atlanta]
...
答案 0 :(得分:1)
试试这个
mapping = {}
cities.each do |city|
city.interstates.each do |interstate|
mapping[interstate] ||= []
mapping[interstate] << city
end
end
答案 1 :(得分:1)
假设假设@ wurde的Hash结构为真,我会做这样的事情
cities = {
'Bakersfield' => {
state: 'California',
interstate: ['I-5']
},
'Oakland' => {
state: 'California',
interstate: ['I-80']
},
'Atlanta' => {
state: 'Georgia',
interstate: ["I-20", "I-75", "I-86"]
},
'Cleveland' => {
state: 'Ohio',
interstate: ["I-71", "I-77", "I-80", "I-90"]
},
'Arlington' => {
state: 'Texas',
interstate: ["I-20", "I-30"]
}
}
cities.each_with_object(Hash.new {|h,k| h[k] = []}) do |(city_name,data),h|
data[:interstate].each do |interstate|
h[interstate] << "#{city_name}, #{data[:state]}"
end
end
#=> {"I-5"=>["Bakersfield, California"],
"I-80"=>["Oakland, California", "Cleveland, Ohio"],
"I-20"=>["Atlanta, Georgia", "Arlington, Texas"],
"I-75"=>["Atlanta, Georgia"],
"I-86"=>["Atlanta, Georgia"],
"I-71"=>["Cleveland, Ohio"],
"I-77"=>["Cleveland, Ohio"],
"I-90"=>["Cleveland, Ohio"],
"I-30"=>["Arlington, Texas"]}
答案 2 :(得分:0)
cities = {
'Bakersfield' => {
state: 'California',
interstate: ['I-5']
},
'Oakland' => {
state: 'California',
interstate: ['I-80']
},
'Atlanta' => {
state: 'Georgia',
interstate: ["I-20", "I-75", "I-86"]
},
'Cleveland' => {
state: 'Ohio',
interstate: ["I-71", "I-77", "I-80", "I-90"]
},
'Arlington' => {
state: 'Texas',
interstate: ["I-20", "I-30"]
}
}
interstates = {}
cities.each do |city|
city[1][:interstate].each do |road|
interstates[road] ||= []
interstates[road] << city[0]
end
end
puts interstates.inspect
#=> {
#=> "I-5"=>["Bakersfield"],
#=> "I-80"=>["Oakland", "Cleveland"],
#=> "I-20"=>["Atlanta", "Arlington"],
#=> "I-75"=>["Atlanta"],
#=> "I-86"=>["Atlanta"],
#=> "I-71"=>["Cleveland"],
#=> "I-77"=>["Cleveland"],
#=> "I-90"=>["Cleveland"],
#=> "I-30"=>["Arlington"]
#=> }
答案 3 :(得分:0)
我们有:
cities = {
'Bakersfield' => ['I-5'],
'Oakland' => ['I-80'],
'Atlanta' => ["I-20", "I-75", "I-86"],
'Cleveland' => ["I-71", "I-77", "I-80", "I-90"],
'Arlington' => ["I-20", "I-30"]
}
更长的版本我们可以通过此操作获得您想要的内容:
require 'set'
interstates = cities.inject(Set.new){|all,item| all+item[1]} # => #<Set: {"I-5", "I-80", "I-20", "I-75", "I-86", "I-71", "I-77", "I-90", "I-30"}>
result = interstates.map{|inter| [inter, cities.select{|_,interstates| interstates.include?(inter)}.keys]}.to_h # => {"I-5"=>["Bakersfield"], "I-80"=>["Oakland", "Cleveland"], "I-20"=>["Atlanta", "Arlington"], "I-75"=>["Atlanta"], "I-86"=>["Atlanta"], "I-71"=>["Cleveland"], "I-77"=>["Cleveland"], "I-90"=>["Cleveland"], "I-30"=>["Arlington"]}
我们使用Set
因为它在给定设置中有效(更优雅的语法,请参阅下面的注释)。在第2行,我们使用interstates
的{{1}}方法获取所有Enumerable
。最终结果在第3行获得,我们使用映射和过滤(inject
和map
方法)。注意,Ruby 2.1提供了select
方法。如果您使用较旧的Ruby,则可以使用to_h
将映射的数组转换为Hash
。
单行它甚至可以写成一行代码:
Hash[array]
注意我在此处添加了cities.inject(Set.new){|all,item| all+item[1]}.map{|inter| [inter, cities.select{|_,interstates| interstates.include?(inter)}.keys]}.to_h
以提高性能。如果您更喜欢可读性,那么只需编写Set
就可以了,如@engineersmnky在评论中所述。
答案 4 :(得分:0)
Using @wurde's example (thank you, thank you, thank you):
cities.each_with_object({}) do |(k,g),h|
g[:interstate].each { |i| h.update(i=>[k]) { |_,o,n| o+n } }
end
#=> {"I-5" =>["Bakersfield"],
# "I-80"=>["Oakland", "Cleveland"],
# "I-20"=>["Atlanta", "Arlington"],
# "I-75"=>["Atlanta"],
# "I-86"=>["Atlanta"],
# "I-71"=>["Cleveland"],
# "I-77"=>["Cleveland"],
# "I-90"=>["Cleveland"],
# "I-30"=>["Arlington"]}
This uses the form of Hash#update (aka merge!
) that uses the block:
{ |_,o,n| o+n }
to determine values of keys that are present in both hashes being merged. The key is the intestate (written _
because it is not be used), o
is an array of cities for the key in the hash h
being constructed and n
is an array of a single city for the merging hash { i=>[k] }
.