2014-05-19 100 views
1

我正在使用LinkedIn API來獲取公司的詳細信息。他們還派遣一個XML響應,所以我只是轉換的XML使用.to_hash方法哈希 這是一個示例哈希我越來越: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

所以你想只從所有部件的位置獲得數據(例如,有城市和POSTAL_CODE和PHONE1第一位置),或者是你快樂混搭(從第一所在地的城市和POSTAL_CODE ,phone1從第二個位置) – SteveTurczyn

+0

不,我需要城市和postal_code從相同的位置和電話號碼可以從任何其他location.This更具有意義full.You不能從一個位置獲得城市和postal_code從其他權利? – Rajanand02

+0

所以你說的位置可能存在,但它可能沒有地址節點,或者它可能沒有聯繫節點。 – SteveTurczyn

回答

1

我認爲這是一個關於代碼自信的問題。也就是說,我敢打賭,你可以想出如何通過所有可能的條件猜測你的方式......但是這會造成一團亂七八糟的代碼。自信的代碼表明它想要什麼,並獲得它並繼續前進。 (注意:我從這本精彩的書中獲得了關於這個話題的所有靈感:Avdi Grimm的http://www.confidentruby.com/)。

這就是說,我會推薦以下內容。

  1. 安裝naught寶石:https://github.com/avdi/naught
  2. 在代碼中,利用Maybe轉換功能(通過寶石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

好吧,這個代碼基本上致力於通過散列而不是(比它搜索的特定節點以外)關注節點名稱

的find_and_get_values方法有兩個參數:目標搜索和陣列的節點查找。如果數組中的所有節點都是同一父節點下的同胞,它將只返回一個結果。 (所以「城市」和「郵政編碼」必須在同一家長之下,否則都不會被返回)

返回的數據是一個簡單的散列。

get_values方法使用一個參數(公司散列)並調用find_and_get_values兩次,一次用於%w(城市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)