我正在使用LinkedIn API来获取公司'细节。他们正在发送XML响应,因此我只是使用.to_hash
方法将XML转换为哈希
这是我得到的示例哈希:http://pastebin.com/1bXtHZ2F
在一些公司,他们有多个地点和联系信息,我想解析这些数据并获取电话号码,城市,邮政编码等详细信息。
响应的结构不一致。有时位置字段本身丢失或postal_code
仅在第四个位置可用。
我尝试了两种方法:
1
def phone(locations)
(locations && locations["values"][0]["contactInfo"]["phone1"]) || nil
end
如果第一个阵列中没有电话号码
,则无效2
def phone(locations)
if locations["locations"]["total"].to_i == 1
locations["locations"]["location"]["contact_info"]["phone1"]
else
locations["locations"]["location"].each do |p|
if (!p["contact_info"]["phone1"].nil? || !p['contact_info'].nil?)
return p["contact_info"]["phone1"]
break
end
end
end
end
如果响应中缺少"location"
哈希本身,则无效。我需要一个解决方案,我可以使用密钥"city"
,"phone"
和"postal_code"
进行搜索,并更新是否存在。如果它返回一个数组,则解析数组并获取非空数据。
我也读过StackOverflow answer。
答案 0 :(得分:1)
我认为这是一个关于代码置信度的问题。也就是说,我打赌你可以弄清楚如何在所有可能的条件下猜测你的方式......但这会产生一堆乱七八糟的不自信的代码。自信的代码陈述了它想要的东西,它得到它并继续前进。 (注意:我从这本精彩的书中得到了我对这个主题的所有灵感:Avdi Grimm的http://www.confidentruby.com/。
那就是说,我推荐以下内容。
naught
gem:https://github.com/avdi/naught Maybe
转换功能(通过gem documetnation了解信息)可以自信地达到您的价值:在班级或管制员的顶层:
NullObject = Naught.build
include NullObject::Conversions
在你的方法中:
def phone(locations)
return {} if locations["location"].blank?
Maybe(locations["locations"])["location"].to_a.inject({}) do |location, acc|
contact_info = Maybe(location["contact_info"])
acc[location][:city] = contact_info["city1"].to_s
acc[location][:phone] = contact_info["phone1"].to_i
acc[location][:postal_code] = contact_info["postal_code1"].to_s
acc
end
end
我不确定你要完成什么,但上述情况可能就是一个开始。它只是试图假设所有的密钥都存在。无论是他们还是他们都没有将它们转换为对象(数组,字符串或整数)。然后,最终收集到一个哈希值(调用acc
- " accumulator" - 上面的循环内部)的缩写,以便返回。
如果上述任何需要澄清,请告诉我,我们可以聊天。
答案 1 :(得分:1)
好的,这段代码基本上是通过哈希工作的,并不关心节点名称(除了它搜索的特定节点)
find_and_get_values方法有两个参数:要搜索的对象和要查找的节点数组。如果数组中的所有节点都是同一父节点下的兄弟节点,它将仅返回结果。 (所以“city”和“postal_code”必须在同一个父级之下,否则都不会返回)
返回的数据是一个简单的哈希值。
get_values方法接受一个参数(公司哈希)并调用find_and_get_values两次,一次用于%w(city postal_code),一次用于%w(phone1)并将哈希结果合并到一个哈希中。
def get_values(company)
answer = {}
answer.merge!(find_and_get_values(company["locations"], %w(city postal_code))
answer.merge!(find_and_get_values(company["locations"], ["phone1"]))
answer
end
def find_and_get_values(source, match_keys)
return {} if source.nil?
if source.kind_of?(Array)
source.each do |sub_source|
result = find_and_get_values(sub_source, match_keys)
return result unless result.empty?
end
else
result = {}
if source.kind_of?(Hash)
match_keys.each do |key|
result[key] = source[key] unless source[key].nil?
end
return result if result.count == match_keys.count
source.each do |sub_source|
result = find_and_get_values(sub_source, match_keys)
return result unless result.empty?
end
end
end
return {}
end
p get_values(company)