2010-07-27 96 views
1
[ 
    { 
     "name": "John Doe", 
     "location": { 
      "name": "New York, New York", 
      "id": 12746342329 
     }, 
     "hometown": { 
      "name": "Brooklyn, New York", 
      "id": 43453644 
     } 
    }, 
    { 
     "name": "Jane Doe", 
     "location": { 
      "name": "Miami, Florida", 
      "id": 12746342329 
     }, 
     "hometown": { 
      "name": "Queens, New York", 
      "id": 12746329 
     } 
    } 
] 

鑑於這塊JSON的,我怎麼會能夠循環並拔出所有的「故鄉」和「位置」鍵,看看哪些人有新的價值紐約嗎?比較多個值在Ruby陣列

我的問題是我可以Array.each通過這些項目,但我不知道如何遍歷我的標準(「紐約」)的兩個位置& &家鄉。

+0

這已更新 – kylemac 2010-07-27 15:01:42

回答

4
people.select {|person| 
    person.any? {|k, v| 
    %w[location hometown].include?(k) && /New York/ =~ v['name'] 
}} 

這基本上是這樣說的:選擇數組中的以下條件爲真的所有條目。條件是:對於任何鍵值對,密鑰是'hometown'還是'location',屬於該密鑰的值的name屬性是否與正則表達式匹配/New York/

但是,您的對象模型似乎嚴重需要重構。事實上,主要的問題是你的對象模型甚至不是一個對象模型,它是一個散列和數組模型。

這裏就是我的意思是通過適當的對象模型:因爲不是戲弄分開的嵌套迷宮bults的堅果

class Person 
    attr_reader :name, :location, :hometown 

    def initialize(name, location=nil, hometown=nil) 
    @name, @location, @hometown = name, location, hometown 
    end 

    def cities 
    return @location, @hometown 
    end 
end 

class City 
    attr_reader :id, :name 

    def initialize(id, name) 
    @id, @name = id, name 
    end 

    def =~(other) 
    name =~ other 
    end 
end 

nyc = City.new(12746342329, 'New York, New York') 
brooklyn = City.new(43453644, 'Brooklyn, New York') 
miami = City.new(12746342329, 'Miami, Florida') 
queens = City.new(12746329, 'Queens, New York') 

john = Person.new('John Doe', nyc, brooklyn) 
jane = Person.new('Jane Doe', miami, queens) 

people = [john, jane] 

如果你有這樣一個合適的對象模型,你的代碼變得乾淨多了,哈希和數組,你有可愛的小物件,你可以簡單地問幾個問題:

people.select {|person| person.cities.any? {|city| city =~ /New York/ }} 

你幾乎可以讀這就像英語:從陣列中選擇其中任何他們的城市的正則表達式匹配/New York/所有的人。

如果我們改善了對象模型進一步,它會變得更好:

class Person 
    def lived_in?(pattern) 
    cities.any? {|city| city =~ pattern } 
    end 
end 

people.select {|person| person.lived_in?(/New York/) } 

這基本上說,「從人民中,選擇在同一時間住在紐約的那些」。這比「從人們選擇所有關鍵值對的第一個元素是字符串'hometown'或字符串'location',並且鍵值對的第二個元素匹配正則表達式/New York/」要好得多。

+0

我已經更新了JSON是有效的,你介意再給它看看嗎? – kylemac 2010-07-27 15:01:13

+0

@ kylemac:它的工作原理。 – 2010-07-27 15:03:40

+0

你介意解釋這裏發生了什麼?我是ruby的新手,這有點超過我的腦海 – kylemac 2010-07-27 15:13:49

1

我覺得約爾格的解決方案有一個小問題 - 「位置」和「家鄉」都沒有用,因此,舉例來說,下面的「人」將通過測試:

{ 
    'name' => 'Foo Bar', 
    'favourite movie' => { 
    name => 'New York, New York!' 
    } 
} 

這裏有一個鏡頭在修正它,以及意見:

ary.select {|person| # get me every person satisfying following condition 
    %w[location hometown].any? {|key| # check if for any of the strings 'location' and 'hometown' 
    # person should have that key, and its 'name' should contain /New York/ regexp 
    person[key] && person[key]['name'] && /New York/ =~ person[key]['name'] 
}} 
+0

+1,謝謝你的注意。主要是我的腦部疾病。我*確實記得要從芝加哥加入一個人到測試集,以便我可以確定過濾器是否正在工作*,但我完全錯過了*特定的角落案例。幹得不錯! (哦,對於IDE來說,如果我已經將這些代碼輸入到我個人最喜歡的NetBeans中,而不是愚蠢的StackOverflow WYSIWIG編輯器和IRB,它會立即將這兩個代碼強調爲「未使用的局部變量」。) – 2010-07-27 22:49:48