简体   繁体   中英

Lodash for loop returns undefined upon using the “i”, but works with set values

I'm trying to search an object for certain integer values using Lodash and then push some of the object values into an array. The integer values have to be variable and come from a different array, but always returns an undefined value

When I hardcode the value like this: _.find(getChampionList.data, { 'key': '266'}) it works perfectly, however if I use a variable from my array it returns undefined.

The object I'm trying to extract data from:

var getChampionList = {
    "type": "champion",
    "format": "standAloneComplex",
    "version": "9.18.1",
    "data": {
        "Aatrox": {
            "version": "9.18.1",
            "id": "Aatrox",
            "key": "266",
            "name": "Aatrox",
            "title": "the Darkin Blade",
            "blurb": "Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...",
            "info": {
                "attack": 8,
                "defense": 4,
                "magic": 3,
                "difficulty": 4
            },
            "image": {
                "full": "Aatrox.png",
                "sprite": "champion0.png",
                "group": "champion",
                "x": 0,
                "y": 0,
                "w": 48,
                "h": 48
            },
            "tags": [
                "Fighter",
                "Tank"
            ],
            "partype": "Blood Well",
            "stats": {
                "hp": 580,
                "hpperlevel": 90,
                "mp": 0,
                "mpperlevel": 0,
                "movespeed": 345,
                "armor": 38,
                "armorperlevel": 3.25,
                "spellblock": 32.1,
                "spellblockperlevel": 1.25,
                "attackrange": 175,
                "hpregen": 3,
                "hpregenperlevel": 1,
                "mpregen": 0,
                "mpregenperlevel": 0,
                "crit": 0,
                "critperlevel": 0,
                "attackdamage": 60,
                "attackdamageperlevel": 5,
                "attackspeedperlevel": 2.5,
                "attackspeed": 0.651
            }
        },
        "Ahri": {
            "version": "9.18.1",
            "id": "Ahri",
            "key": "103",
            "name": "Ahri",
            "title": "the Nine-Tailed Fox",
            "blurb": "Innately connected to the latent power of Runeterra, Ahri is a vastaya who can reshape magic into orbs of raw energy. She revels in toying with her prey by manipulating their emotions before devouring their life essence. Despite her predatory nature...",
            "info": {
                "attack": 3,
                "defense": 4,
                "magic": 8,
                "difficulty": 5
            },
            "image": {
                "full": "Ahri.png",
                "sprite": "champion0.png",
                "group": "champion",
                "x": 48,
                "y": 0,
                "w": 48,
                "h": 48
            },
            "tags": [
                "Mage",
                "Assassin"
            ],
            "partype": "Mana",
            "stats": {
                "hp": 526,
                "hpperlevel": 92,
                "mp": 418,
                "mpperlevel": 25,
                "movespeed": 330,
                "armor": 20.88,
                "armorperlevel": 3.5,
                "spellblock": 30,
                "spellblockperlevel": 0.5,
                "attackrange": 550,
                "hpregen": 6.5,
                "hpregenperlevel": 0.6,
                "mpregen": 8,
                "mpregenperlevel": 0.8,
                "crit": 0,
                "critperlevel": 0,
                "attackdamage": 53.04,
                "attackdamageperlevel": 3,
                "attackspeedperlevel": 2,
                "attackspeed": 0.668
            }
        }
    }
}

var championIds = [ 266, 103 ]

    for (i = 0; i < championIds.length; i++) {
         var champion = _.find(getChampionList.data, { 'key': championIds[i]})
         console.log(champion) //returns undefined
         championArray.push(champion.id) //creates an error
      }

The line var champion = _.find(getChampionList.data, { 'key': championIds[i]}) should return the objects and then push the "id" field into "championArray". Hardcoded like this { 'key': '266'} it returns the object for Aatrox, but with the championIds[i] it just gives an undefined value (while championIds[0] does return "266").

I'm not sure what's wrong with my code, but perhaps it has to do with Lodash or a typing mistake? I've been looking at it for hours console.logging every line, but can't see what's wrong.

You will need to do three things:

  1. Since you "know" you need to locate the key values, start with championData.data
  2. Reduce objects (key-value pairs) to a list
  3. Parse the key as an integer

Alternatively, you could map and filter.

 let championData = getData(), championIds = [ 266, 103 ], championList = Object.keys(championData.data).reduce((list, name) => { return championIds.includes(parseInt(championData.data[name].key, 10))? list.concat(championData.data[name].id): list; }, []); console.log(championList); function getData() { return { "type": "champion", "format": "standAloneComplex", "version": "9.18.1", "data": { "Aatrox": { "version": "9.18.1", "id": "Aatrox", "key": "266", "name": "Aatrox", "title": "the Darkin Blade", "blurb": "Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...", "info": { "attack": 8, "defense": 4, "magic": 3, "difficulty": 4 }, "image": { "full": "Aatrox.png", "sprite": "champion0.png", "group": "champion", "x": 0, "y": 0, "w": 48, "h": 48 }, "tags": [ "Fighter", "Tank" ], "partype": "Blood Well", "stats": { "hp": 580, "hpperlevel": 90, "mp": 0, "mpperlevel": 0, "movespeed": 345, "armor": 38, "armorperlevel": 3.25, "spellblock": 32.1, "spellblockperlevel": 1.25, "attackrange": 175, "hpregen": 3, "hpregenperlevel": 1, "mpregen": 0, "mpregenperlevel": 0, "crit": 0, "critperlevel": 0, "attackdamage": 60, "attackdamageperlevel": 5, "attackspeedperlevel": 2.5, "attackspeed": 0.651 } }, "Ahri": { "version": "9.18.1", "id": "Ahri", "key": "103", "name": "Ahri", "title": "the Nine-Tailed Fox", "blurb": "Innately connected to the latent power of Runeterra, Ahri is a vastaya who can reshape magic into orbs of raw energy. She revels in toying with her prey by manipulating their emotions before devouring their life essence. Despite her predatory nature...", "info": { "attack": 3, "defense": 4, "magic": 8, "difficulty": 5 }, "image": { "full": "Ahri.png", "sprite": "champion0.png", "group": "champion", "x": 48, "y": 0, "w": 48, "h": 48 }, "tags": [ "Mage", "Assassin" ], "partype": "Mana", "stats": { "hp": 526, "hpperlevel": 92, "mp": 418, "mpperlevel": 25, "movespeed": 330, "armor": 20.88, "armorperlevel": 3.5, "spellblock": 30, "spellblockperlevel": 0.5, "attackrange": 550, "hpregen": 6.5, "hpregenperlevel": 0.6, "mpregen": 8, "mpregenperlevel": 0.8, "crit": 0, "critperlevel": 0, "attackdamage": 53.04, "attackdamageperlevel": 3, "attackspeedperlevel": 2, "attackspeed": 0.668 } } } }; }
 .as-console-wrapper { top: 0; max-height: 100%;important; }

You use _.find() correctly. Find doesn't work because the keys are strings, and you're looking for numbers:

 var getChampionList = {"type":"champion","format":"standAloneComplex","version":"9.18.1","data":{"Aatrox":{"version":"9.18.1","id":"Aatrox","key":"266","name":"Aatrox","title":"the Darkin Blade","blurb":"Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...","info":{"attack":8,"defense":4,"magic":3,"difficulty":4},"image":{"full":"Aatrox.png","sprite":"champion0.png","group":"champion","x":0,"y":0,"w":48,"h":48},"tags":["Fighter","Tank"],"partype":"Blood Well","stats":{"hp":580,"hpperlevel":90,"mp":0,"mpperlevel":0,"movespeed":345,"armor":38,"armorperlevel":3.25,"spellblock":32.1,"spellblockperlevel":1.25,"attackrange":175,"hpregen":3,"hpregenperlevel":1,"mpregen":0,"mpregenperlevel":0,"crit":0,"critperlevel":0,"attackdamage":60,"attackdamageperlevel":5,"attackspeedperlevel":2.5,"attackspeed":0.651}},"Ahri":{"version":"9.18.1","id":"Ahri","key":"103","name":"Ahri","title":"the Nine-Tailed Fox","blurb":"Innately connected to the latent power of Runeterra, Ahri is a vastaya who can reshape magic into orbs of raw energy. She revels in toying with her prey by manipulating their emotions before devouring their life essence. Despite her predatory nature...","info":{"attack":3,"defense":4,"magic":8,"difficulty":5},"image":{"full":"Ahri.png","sprite":"champion0.png","group":"champion","x":48,"y":0,"w":48,"h":48},"tags":["Mage","Assassin"],"partype":"Mana","stats":{"hp":526,"hpperlevel":92,"mp":418,"mpperlevel":25,"movespeed":330,"armor":20.88,"armorperlevel":3.5,"spellblock":30,"spellblockperlevel":0.5,"attackrange":550,"hpregen":6.5,"hpregenperlevel":0.6,"mpregen":8,"mpregenperlevel":0.8,"crit":0,"critperlevel":0,"attackdamage":53.04,"attackdamageperlevel":3,"attackspeedperlevel":2,"attackspeed":0.668}}}} var championIds = [266, 103] var championArray = [] for (i = 0; i < championIds.length; i++) { var champion = _.find(getChampionList.data, { 'key': String(championIds[i]) // convert the championIds[i] to String }) championArray.push(champion.id) } console.log(championArray)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

However, this is it not really efficient, since each search loop starts from the beginning. If you've got a short data collection, you want see any difference. However, for long data , you can use _.intersectionWith() to find the items with the relevant keys, and then use _.map() to extract the id values.

 var getChampionList = {"type":"champion","format":"standAloneComplex","version":"9.18.1","data":{"Aatrox":{"version":"9.18.1","id":"Aatrox","key":"266","name":"Aatrox","title":"the Darkin Blade","blurb":"Once honored defenders of Shurima against the Void, Aatrox and his brethren would eventually become an even greater threat to Runeterra, and were defeated only by cunning mortal sorcery. But after centuries of imprisonment, Aatrox was the first to find...","info":{"attack":8,"defense":4,"magic":3,"difficulty":4},"image":{"full":"Aatrox.png","sprite":"champion0.png","group":"champion","x":0,"y":0,"w":48,"h":48},"tags":["Fighter","Tank"],"partype":"Blood Well","stats":{"hp":580,"hpperlevel":90,"mp":0,"mpperlevel":0,"movespeed":345,"armor":38,"armorperlevel":3.25,"spellblock":32.1,"spellblockperlevel":1.25,"attackrange":175,"hpregen":3,"hpregenperlevel":1,"mpregen":0,"mpregenperlevel":0,"crit":0,"critperlevel":0,"attackdamage":60,"attackdamageperlevel":5,"attackspeedperlevel":2.5,"attackspeed":0.651}},"Ahri":{"version":"9.18.1","id":"Ahri","key":"103","name":"Ahri","title":"the Nine-Tailed Fox","blurb":"Innately connected to the latent power of Runeterra, Ahri is a vastaya who can reshape magic into orbs of raw energy. She revels in toying with her prey by manipulating their emotions before devouring their life essence. Despite her predatory nature...","info":{"attack":3,"defense":4,"magic":8,"difficulty":5},"image":{"full":"Ahri.png","sprite":"champion0.png","group":"champion","x":48,"y":0,"w":48,"h":48},"tags":["Mage","Assassin"],"partype":"Mana","stats":{"hp":526,"hpperlevel":92,"mp":418,"mpperlevel":25,"movespeed":330,"armor":20.88,"armorperlevel":3.5,"spellblock":30,"spellblockperlevel":0.5,"attackrange":550,"hpregen":6.5,"hpregenperlevel":0.6,"mpregen":8,"mpregenperlevel":0.8,"crit":0,"critperlevel":0,"attackdamage":53.04,"attackdamageperlevel":3,"attackspeedperlevel":2,"attackspeed":0.668}}}} var championIds = [266, 103] var championArray = _.map( _.intersectionWith( _.values(getChampionList.data), // get an array of data items championIds, (a, b) => a.key == b // use loose equality that ignores the type ), 'id') // extract the id using map console.log(championArray)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM