2015-06-20 123 views
2

这是我的JSON,我想直接从JSON获取zipCodes值,而无需循环JSON。我该怎么做?访问JSON中的嵌套值,不通过循环访问

countries:[ 
      { 
       name:'India', 
       states:[{ 
          name:'Orissa', 
          cities:[{ 
             name:'Sambalpur', 
             zipCodes:{'768019','768020'} 
            }] 
         }] 
      } 
      ] 
+0

你不能。除非你已经知道阵列中的位置。假设你刚刚展示了一个样本,并且你的真实数据有很多国家,每个国家都有许多州和城市? – nnnnnn

+0

@ vihan1086 - 是的,但“时髦的技巧”实际上并没有比循环播放更好,是吗?我的意思是,你可以例如在(未解析的)JSON上使用正则表达式,但你为什么要这样做? – nnnnnn

+0

@nnnnnn是的,所以有很多数据要遍历,我想知道是否有任何有效的方法来做到这一点。 – user1502144

回答

1

我认为你正在寻找

countries[0].states[0].cities[0].zipCodes 

请注意,这适用于上述JSON因为只有1个国家排列的国家,相同州和城市。但是,如果有超过1个国家,州或城市,那么您将不得不重复提取信息,除非您知道确切的指数。

+0

这只是一个示例数据,真正的JSON非常大,每个国家都有多个州,城市和邮编,我想获得特定国家的所有邮编。 – user1502144

+0

然后你必须迭代提取信息。 – nikhil

1

由于这不是一个关联数组,你的选择是只使用索引这样的:

countries[x].states[y].cities[0].zipCodes 

x将是你的阵列中的每个状态表示,在情况下,当然,前提是你有超过一个。

类似的,y将在每个国家的每个州的每个州,以防你有更多的这些,如果你需要,你可以做同样的城市。

编辑: 这里是你如何遍历数组:

for(var c in countries) 
{ 
    var name = countries[c].name; 
    if (name === "CountryIAmLookingFor") 
    { 
     var statesList = countries[c].states; 
     for (var s in statesList) 
     { 
      var stateName = statesList[s].name; 
      ..... 
     } 
    } 
} 

你可以继续迭代,直到找到国家,州,和你需要的城市,然后提取从那里zipCodes如在前面代码片段。

+0

这只是一个示例数据,真正的JSON非常大,每个国家都有多个州,城市和邮编,我想获得特定国家的所有邮编。 – user1502144

+0

如上所述,您将不得不迭代并检查每个值,直到找到您要查找的内容。您可以用整数替换数组中包含的每个项目的X,并检查每个步骤如果countries [x] .name与您正在搜索的国家/地区的名称相同,然后对州和城市执行相同的操作,直到您找到您需要的详细程度并从中提取zipCodes。这有意义吗? – mmvsbg

+0

我已经编辑了上面的答案以包含迭代循环,因此您可以通过整个数组找到所需的数据。 – mmvsbg

0

没有“循环”

你可以做这个疯狂的招(不是说这是最好的方式,但你不通过JSON循环这样)

var myData = { 'Put Your Data': 'HERE' }; 
function getCodes(name, data) { 
    var sv = data.match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = []; 
    sv.forEach(function (item) { 
     item.match(/\d+/g).forEach(function (sub) { 
      r.push(+sub); 
     }); 
    }); 
    return r; 
} 
getCodes('India', JSON.stringify(myData)); 

如果你的数据已经是字符串,那么你不需要JSON.stringify。您看到的forEach实际上并不是通过JSON“循环”。它已经提取了邮政编码,代码只是将邮政编码添加到数组中。 。这条线:

var sv = JSON.stringify(data).match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = []; 

是很有吸引力的邮政编码,它会是这样的:

["zipCodes":["768019","768020"]"] 

下一行:

item.match(/\d+/g) 

会抢了号码,如输出的东西:

["768019", "768020"] 

The loo p只是增加了拉链码到另一个阵列

随着循环

你最好通过JSON循环:

var myData = {}, // Your data 
    zips = []; 

myData.countries.forEach(function(i) { 
    if (i.name === 'India') { 
     i.states.forEach(function(j) { 
      j.cities.forEach(function(l) { 
       l.zipCodes.forEach(function(m) { 
        zips.push(m); 
       }); 
      }); 
     }); 
    } 
}); 

//use "zips" array 

性能和速度测试

经过测试复制阵列500MB(半个演出)花费约30秒。好多啊。考虑到一个非常大的JSON将约为5MB,循环通过一点点5MB的JSON需要约0.14秒。你不应该担心速度。

+1

除非OP在字符串形式中引用JSON,否则这是一个无效的答案。 'JSON.stringify'比“循环JSON”要贵很多。 –

+0

@PatrickRoberts我意识到这一点,我提到它可能不是很好,它是一个“窍门”。问题在于没有循环访问嵌套值,这正是我所做的。我的回答完全回答了OP的问题,并且没有错。 – Downgoat

+0

如果您只是在寻找一个不合适的“技巧”,那么您可以从函数的值中获取“JSON.stringify”的第二个参数的值,并且如果该键等于“zipCodes”,则将该值推送到数组中。 –

1

这是我的“诀窍”,以避免显式迭代。让JSON.parseJSON.stringify为你做的工作。如果您的JSON是字符串形式,试试这个:

var array = []; 

JSON.parse(jsonString, function (key, value) { 
    if (key === "zipCodes") { 
     array = array.concat(value); 
    } 

    return value; 
}); 

console.log(array); // all your zipCodes 
+0

这将返回一个数组,如:[[“768019”,“768020”],[012]] – Downgoat

+0

@ vihan1086展平它 –

+0

以前从未听说过'array.concat',有趣... – Downgoat

0

假设您的JSON是像

countries =[ 
      { 
       name:'India', 
       states:[{ 
          name:'Orissa', 
          cities:[{ 
             name:'Sambalpur', 
             zipCodes:768019768020 
            }] 
         },{ 
          name:'mumbai', 
          cities:[{ 
             name:'rea', 
             zipCodes:324243 
            }] 
         }] 
      } 
     ] 

所以,现在我们使用地图,它会给你邮编每个城市

countries.map(function(s){ 
    s.states.map(function(c){ 
     c.cities.map(function(z){ 
     console.log(z.zipCodes) 

     }) 
    }) 
}) 

OR

如果使用return语句,然后它会给你2阵列有两个邮政编码为每过JSON

var finalOP = countries.map(function(s){ 
    var Stalist = s.states.map(function(c){ 
     var zip = c.cities.map(function(z){ 

     return z.zipCodes 
     }) 
     return zip 
    }) 
    return Stalist 
}) 

console.log(finalOP)