2017-02-20 130 views
0

讓特定的信息說,我有以下格式的數組:獲得從多維數組

arr = [{ 
     "id":"11", 
     "children":[ 
         { "id":"9"}, 
         { "id":"5", "children":[ {"id":"4"} ] } 
        ] 
     }, 
     { 
     "id":"10", 
     "children":[{ "id":"7"} ] 
     } 
     ] 

現在我想獲得所有的ID,此數組中是顯而易見的:

11,9,5,4,10,7 

爲此,我會使用類似一個遞歸碼:

ids = [] 

def find_ids arr 
arr.each do |entry| 
    ids << entry["id"] if entry["id"] 
    find_ids(entry["children"]) if entry["children"] 
end 
end 

你會做什麼來獲得ID?

你也許知道一個非常短的版本?

感謝

+1

約翰,我相信編輯我做與你同在。我重新格式化輸入數組以顯示其結構,並避免讀者水平滾動以查看它。我還附加了一個變量('arr'),以便讀者可以引用該變量而不必定義它。這將有助於(無論何時舉例)將您想要的結果顯示爲Ruby對象。在這裏你可能會要求'[11,9,5,4,10,7]'。 –

+0

除非您希望將字符串轉換爲整數,否則請設置[[「11」,「9」,「5」,「4」,「10」,「7」]''。 –

+0

在發佈我的答案之前,我沒有仔細閱讀過您的問題,這與您的建議幾乎相同,除非我允許鍵值不是「:id」且值不是數組的鍵值對。注意'{「id」:1}#=> {:id => 1}',也就是說,引號是多餘的(只有當字符串包含空格時才需要引號('{「ab」:1}#= > {:「ab」=> 1}')。因此,'{「id」:1} [「id」]#=> nil'。''{id:1} [:id]#= > 1'。 –

回答

0

或者,如果你想使用更短的版本:

def get_ids(arr) 
    p =->(hsh) { Array === hsh["children"] ? ([hsh["id"]] + hsh["children"].map(&p)) : hsh["id"] } 

    arr.map(&p).flatten 
end 

get_ids(arr) 
# => ["11", "9", "5", "4", "10", "7"] 
1
def grab_ids(arr) 
    arr.each_with_object([]) do |h,a| 
    h.each do |k,v| 
     case v 
     when Array 
     a.concat(grab_ids(v)) 
     else 
     a << v if k == :id 
     end 
    end 
    end 
end 

grab_ids arr 
    #=> ["11", "9", "5", "4", "10", "7"] 
1

另一種方法是使用拉姆達:

def get_ids(arr) 
    p = ->(a, exp) do 
    a.each do |hsh| 
     exp << hsh["id"] 
     p.(hsh["children"], exp) if Array === hsh["children"] 
    end 
    exp 
    end 
    p.(arr, []) 
end 

get_ids(arr) 
# => ["11", "9", "5", "4", "10", "7"]