【问题标题】:PokeAPI + Angular: How to get pokemon's evolution chainPokeAPI + Angular:如何获得口袋妖怪的进化链
【发布时间】:2016-12-30 23:20:04
【问题描述】:

我是 Angular 新手,我通过尝试使用 pokeapi 拉动每个 pokemon 的进化链来学习一点,但由于深度嵌套而遇到困难。

一个典型的响应对象是这样返回的:

{
  "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(如果不为空)

但是正如你所看到的,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 对象。

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    你总是可以避免使用 Angular 并坚持使用普通的 JS 来构建你的进化链......试试这个,它是基于你的角度 for 循环。这应该会为您留下一个对象数组 (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
    }]
    

    【讨论】:

    • 这和你说的完全一样,哇!为了学习,我会尝试研究这个,看看我是否可以做一些类似“角度方式”的事情,但这很好,谢谢!
    • 虽然对于具有多重进化的口袋妖怪来说,这只会推动第一个口袋妖怪
    【解决方案2】:

    如果有多个进化,例如 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;
    

    【讨论】:

      【解决方案3】:

      brandudno 是正确的:额外的if(numberOfEvolutions) 是更完整的方法(感谢@brandudno!这确实帮助我解决了所有用例 - 包括eevee!)

      我喜欢在while 语句中使用!!evoData,因为我花时间去理解它,但一开始我就感到困惑,所以我做了一个小修改,它仍然有效,可能更容易理解其他新开发者(持续到 evoData 变为 undefined)。

      最后,我做了一个小改动,以防其他人也更喜欢使用 . 注释 (evoData.evolves_tovs.evoData['evolves_to']`) 来利用自动完成等功能。

      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;
      

      【讨论】:

        【解决方案4】:

        我正在使用递归函数来解决这个问题。 以下是纯 JavaScript 的用法。

        let evoChain = [];
        
        function getEvo(arr) {
          if (arr[0].evolves_to.length > 0) {
            evoChain.push(arr[0].species.name);
            getEvo(arr[0].evolves_to);
          } else {
            evoChain.push(arr[0].species.name);
            return 0;
          }
        }
        getEvo([data.chain]);```
        

        【讨论】:

          猜你喜欢
          • 2020-09-18
          • 2021-01-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-10
          • 1970-01-01
          相关资源
          最近更新 更多