从多维数组中获取特定信息

Get specific information from multi-dimensional array

假设我有一个这种格式的数组:

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?

你知道一个很短的版本吗?

谢谢

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"]

其他方法是使用 lambda:

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"]

或者如果您想使用较短的版本:

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"]