在JSON中搜索最长路径

时间:2014-10-20 03:39:20

标签: javascript ruby json

我想知道是否有一种快速的方法可以找到下面JSON中获取最长路径的解决方案。结果应该是4或[“Phnom Penh”,“Doun Penh”,“Phsa Thmey”,“Phsa Thmey One”]

{
"name": "Phnom Penh",
"code": "PP",
"sub": [
    {
        "name": "Reousey Keo",
        "code": "RK",
        "sub": {
            "name": "Toul Sangke",
            "code": "TSK"
        }
    },
    {
        "name": "Doun Penh",
        "code": "DP",
        "sub": {
            "name": "Phsa Thmey",
            "code": "PT",
            "sub": {
                "name": "Phsa Thmey One",
                "code": "PTO"
            }
        }
    },
    {
        "name": "Mean Chey",
        "code": "MC",
        "sub": {
            "name": "Nerot",
            "code": "NR"
        }
    }
    ]
},
{
    "name": "Kandal",
    "code": "KD"
}

1 个答案:

答案 0 :(得分:1)

这种递归方法应该适用于任何数组和散列的嵌套(尽管我怀疑它可以简化一些)。在这里,我假设密钥:sub没有什么特别之处,因此代码可以用于(例如)片段:

{
  name: "Doun Penh",
  code: "DP",
  hub: {
    name: "Toledo" }
    code: "TOL"
  }
  bub: {
    name: "Phsa Thmey",
    code: "PT",
    dub: {
      name: "Phsa Thmey One",
      code: "PTO"
    }
  }
}

下面的代码对从JSON字符串构造的数组进行操作。

<强>代码

def deepest(obj, key, dsf={ depth: 0, path: [] })
  dsf_below = dsf.dup
  case obj
  when Array
   obj.each_with_index do |o,i|
     d = deepest(o, key, { depth: dsf[:depth], path: dsf[:path] + [i] } )
     if d[:depth] > dsf_below[:depth]
       dsf_below = d
     end
   end
  when Hash
   if obj.key?(key)
     dkey = { depth: dsf[:depth]+1, path: dsf[:path] + [obj[key]] }
     if dkey[:depth] > dsf_below[:depth]
       dsf_below = dkey
     end
     obj.each do |k,v|
       if (v.is_a? Array) || (v.is_a? Hash)
         d = deepest(v, key, { depth: dkey[:depth], path: dkey[:path] + [k] } )
         if d[:depth] > dsf_below[:depth]
           dsf_below = d
         end
       end
     end
   end
  end
  dsf_below
end

示例

arr = [
  {
    name: "Phnom Penh",
    code: "PP",
    sub: [
      { 
        name: "Reousey Keo",
        code: "RK",
        dub: {
          name: "Toul Sangke",
          code: "TSK" } },
      {
        name: "Doun Penh",
        code: "DP",
        bub: {
          name: "Phsa Thmey",
          code: "PT",
          gub: {
            name: "Phsa Thmey One",
            code: "PTO" } } },
      {
        name: "Mean Chey",
        code: "MC",
        hub: {
          name: "Nerot",
          code: "NR" } } ] },
  {
    name: "Kandal",
    code: "KD" } ]

deepest(arr, :name)
  #=> {:depth=>4, :path=>[0, "Phnom Penh", :sub, 1, "Doun Penh",
  #    :bub, "Phsa Thmey", :gub, "Phsa Thmey One"]}