【问题标题】:Get specific information from multi-dimensional array从多维数组中获取特定信息
【发布时间】:2017-07-09 04:18:33
【问题描述】:

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

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?

你可能知道一个非常短的版本吗?

谢谢

【问题讨论】:

  • 约翰,我相信我所做的编辑对你来说没问题。我重新格式化了输入数组以显示其结构并避免读者需要水平滚动才能看到它。我还为它附加了一个变量 (arr),因此读者可以引用该变量而无需定义它。将您想要的结果显示为 Ruby 对象会很有帮助(无论何时给出示例)。在这里你可能会要求[11, 9, 5, 4, 10, 7]
  • 将其设为["11", "9", "5", "4", "10", "7"],除非您希望将字符串转换为整数。
  • 我在发布答案之前没有仔细阅读您的问题,这与您的建议几乎相同,除了我允许键不是 :id 且值为不是数组。注意{ "id": 1 } #=&gt; {:id=&gt;1},即引号是多余的(并且仅当字符串包含空格时才需要({"a b": 1 } #=&gt; {:"a b"=&gt;1})。因此,{ "id": 1 }["id"] #=&gt; nil。您需要{ id: 1 }[:id] #=&gt; 1
  • arr 具有交替的嵌套数组和散列(到任何级别)时,您确实需要递归来获得所需的数组。如果arr的结构和例子一样固定,只允许非数组值变化,那么,是的,有一个更简单的方法。

标签: ruby-on-rails arrays ruby ruby-on-rails-3


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    其他方法是使用 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"]
    

    【讨论】:

      【解决方案3】:
      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"]
      

      【讨论】:

        猜你喜欢
        • 2020-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多