我是一名Angular新手并且通过尝试使用pokeapi拉动每个口袋妖怪的进化链但是因为深度嵌套而度过了困难而学习了一点。
返回典型的响应对象:
{
"baby_trigger_item": null,
"id": 2,
"chain": {
"evolution_details": [],
"evolves_to": [
{
"evolution_details": [
{
"min_level": 16,
"min_beauty": null,
"time_of_day": "",
"gender": null,
"relative_physical_stats": null,
"needs_overworld_rain": false,
"turn_upside_down": false,
"item": null,
"trigger": {
"url": "http://pokeapi.co/api/v2/evolution-trigger/1/",
"name": "level-up"
},
"known_move_type": null,
"min_affection": null,
"party_type": null,
"trade_species": null,
"party_species": null,
"min_happiness": null,
"held_item": null,
"known_move": null,
"location": null
}
],
"evolves_to": [
{
"evolution_details": [
{
"min_level": 36,
"min_beauty": null,
"time_of_day": "",
"gender": null,
"relative_physical_stats": null,
"needs_overworld_rain": false,
"turn_upside_down": false,
"item": null,
"trigger": {
"url": "http://pokeapi.co/api/v2/evolution-trigger/1/",
"name": "level-up"
},
"known_move_type": null,
"min_affection": null,
"party_type": null,
"trade_species": null,
"party_species": null,
"min_happiness": null,
"held_item": null,
"known_move": null,
"location": null
}
],
"evolves_to": [],
"is_baby": false,
"species": {
"url": "http://pokeapi.co/api/v2/pokemon-species/6/",
"name": "charizard"
}
}
],
"is_baby": false,
"species": {
"url": "http://pokeapi.co/api/v2/pokemon-species/5/",
"name": "charmeleon"
}
}
],
"is_baby": false,
"species": {
"url": "http://pokeapi.co/api/v2/pokemon-species/4/",
"name": "charmander"
}
}
}
我必须访问evolves_to属性,并获取species.name以及evolution_details.min_level和evolution_details.trigger.name,以及evolution_details.item(如果不为null)
但正如你所看到的,evolves_to属性本身包含另一个evolves_to嵌套在里面,里面有另一个嵌套
这是我的悲惨尝试(在http.get之后),我现在只是被卡住了。
var evoObject = response.data;
function loopEvo(obj){
angular.forEach(obj, function(value, key, object){
if (key == 'evolves_to' && value != []) {
//from here I can get top level data, but...
}
});
}
loopEvo(evoObject.chain);
我不知道如何以递归方式潜入对象并不断获取数据,任何人都可以提供任何帮助吗?我希望在遍历复杂的json对象时使用它作为一个很好的学习机会。
答案 0 :(得分:3)
你总是可以避免使用Angular并坚持使用普通的JS来构建你的进化链......尝试给它一个去,它是基于你的角度循环。这应该为您提供一个数组(evoChain
)的对象,其中包含您要查找的数据,从0索引处的第一个进化到最后一个索引的最后进化。
var evoChain = [];
var evoData = response.data.chain;
do {
var evoDetails = evoData['evolution_details'][0];
evoChain.push({
"species_name": evoData.species.name,
"min_level": !evoDetails ? 1 : evoDetails.min_level,
"trigger_name": !evoDetails ? null : evoDetails.trigger.name,
"item": !evoDetails ? null : evoDetails.item
});
evoData = evoData['evolves_to'][0];
} while (!!evoData && evoData.hasOwnProperty('evolves_to'));
在上面的示例中,结果数组应如下所示:
[{
"species_name": "charmander",
"min_level": 1,
"trigger_name": null,
"item": null
}, {
"species_name": "charmeleon",
"min_level": 16,
"trigger_name": "level-up",
"item": null
}, {
"species_name": "charizard",
"min_level": 36,
"trigger_name": "level-up",
"item": null
}]
答案 1 :(得分:0)
如果有多个演变版本(例如Eevee或Snorunt),则上面批准的答案不起作用。那只会返回第一次进化蒸气
以下内容检查演变的数量并遍历所有变化。
let evoChain = [];
let evoData = chain.chain;
do {
let numberOfEvolutions = evoData['evolves_to'].length;
evoChain.push({
"species_name": evoData .species.name,
"min_level": !evoData ? 1 : evoData .min_level,
"trigger_name": !evoData ? null : evoData .trigger.name,
"item": !evoData ? null : evoData .item
});
if(numberOfEvolutions > 1) {
for (let i = 1;i < numberOfEvolutions; i++) {
evoChain.push({
"species_name": evoData.evolves_to[i].species.name,
"min_level": !evoData.evolves_to[i]? 1 : evoData.evolves_to[i].min_level,
"trigger_name": !evoData.evolves_to[i]? null : evoData.evolves_to[i].trigger.name,
"item": !evoData.evolves_to[i]? null : evoData.evolves_to[i].item
});
}
}
evoData = evoData['evolves_to'][0];
} while (!!evoData && evoData.hasOwnProperty('evolves_to'));
return evoChain;
答案 2 :(得分:0)
brandudno是正确的:额外的if(numberOfEvolutions)
是更完整的方法(感谢@brandudno!这确实帮助我解决了所有用例-包括eevee!)
我喜欢花时间去理解!!evoData
语句中的while
用法,但是一开始它对我来说还是很困惑,所以我做了一个较小的修改,仍然可以使用,对于其他新开发人员来说可能会更容易(直到evoData变为undefined
为止。)
最后,我做了些微改动,以防其他人也喜欢使用.
批注(evoData.evolves_to vs.
evoData ['evolves_to']`)以利用自动完成功能,等等。< / p>
let evoChain = [];
let evoData = chain.chain;
do {
let numberOfEvolutions = evoData.evolves_to.length;
evoChain.push({
"species_name": evoData .species.name,
"min_level": !evoData ? 1 : evoData .min_level,
"trigger_name": !evoData ? null : evoData .trigger.name,
"item": !evoData ? null : evoData .item
});
if(numberOfEvolutions > 1) {
for (let i = 1;i < numberOfEvolutions; i++) {
evoChain.push({
"species_name": evoData.evolves_to[i].species.name,
"min_level": !evoData.evolves_to[i]? 1 : evoData.evolves_to[i].min_level,
"trigger_name": !evoData.evolves_to[i]? null : evoData.evolves_to[i].trigger.name,
"item": !evoData.evolves_to[i]? null : evoData.evolves_to[i].item
});
}
}
evoData = evoData.evolves_to[0];
} while (evoData != undefined && evoData.hasOwnProperty('evolves_to'));
return evoChain;