I've got this array
var enemy = {
'level1' : {
creature :
{
creature_name : {
'Goblin' : {
info: {
'c_name' : 'Goblin',
'HP' : '20',
'damage' : '3',
'loot' : [
{name: 'a wooden sword' , item: 'weapon' , value: 2},
{name: 'a golden necklace', item: 'amulet' , value: 1},
{name: 'a pair of boots' , item: 'boots' , value: 1},
{name: 'some cloth legs' , item: 'legs' , value: 1},
{name: 'a cloth helmet' , item: 'helm' , value: 1}
]
}
},
'Cow' : {
info: {
'c_name' : 'Cow',
'HP' : '10',
'damage' : '1',
'loot' : [
{name: 'bell' , item: 'weapon' , value: 0},
{name: 'cow hide cloak' , item: 'cape' , value: 1},
{name: 'a wooden sword' , item: 'weapon' , value: 2},
{name: 'a golden necklace' , item: 'amulet' , value: 1},
]
}
},
'Dragon' : {
info: {
'c_name' : 'Dragon',
'HP' : '100',
'damage' : '5',
'loot' : [
{name: 'an almighty dragon sword' , item: 'weapon' , value: 5},
{name: 'a dragon tooth', item: 'amulet' , value: 5},
{name: 'a pair of dragon boots' , item: 'boots' , value: 4},
{name: 'a dragon helmet' , item: 'helm' , value: 4}
]
}
},
}
},
},
I want to receive the _creature_name_. I saw foreach loops with arrayname.length but when I try to do enemy.length or enemy.level1.creature.creature_name.length then I get undefined.
4 Answers 4
Objects (key/value pairs) don't have an intrinsic .length property.
To just get the names as an array you could use:
var names = Object.keys(enemy.level1.creature.creature_name);
or alternatively to just iterate directly over each name:
for (var name in enemy.level1.creature.creature_name) {
...
}
Regarding the actual content you're after, you could use:
$('#enemy_list').html('Enemies: <br/>Level1: <br/>' +
Object.keys(enemy.level1.creature.creature_name).join('<br/>'));
or:
var content = ['Enemies:', 'Level1:'].concat(Object.keys(enemy.level1.creature.creature_name));
$('#enemy_list').html(content.join('<br/>'));
5 Comments
var names = Object.keys(enemy.level1.creature.creature_name); for(var i = 0; i < names.length; i++){ $('#enemy_list')[0].innerHTML += 'Enemies: <br />Level 1: <br />' + names[i] + '<br />'; } It places it individually.But.. for example the result is dragon , cow , goblin it places it below each other (which is correct) but ALSO places it 3 times instead of once.+= with .innerHTML - make a single string variable and then put that in .innerHTMLSince objects don't have length properties assigned to the number of properties inside one solution would be to loop classically through the object as following:
for(var prop in enemy['level1'].creature.creature_name){
console.log(prop)
}
This will print out the name one by one
I prepared it in a jsfiddle also: https://jsfiddle.net/fo8xjr8w/
Comments
var creature_name = enemy.level1.creature.creature_name;
for (var prop in creature_name)
{
console.log(prop);
//this would print Goblin, Cow, Dragon
}
You again have to iterate if you want to traverse further internal details for the loot array.
1 Comment
hasOwnProperty check.$('#enemy_list')[0].innerHTML = 'Enemies: <br />Level 1: <br />';
for(var enemy_names in enemy['level1'].creature.creature_name){
$('#enemy_list')[0].innerHTML += enemy_names + '<br />';
}
You need create a prop for the name inenemy['level1'].creature.creature_name and then foreach enemy_name place it in the containing div. Goodluck!
By the way, your problem with the for loop was that you executed the enemies: <br /> level1: <br /> in your for loop aswell so it would display it 3 times. This method you put the names inside the div containing the text only once.
6 Comments
+= with .innerHTML - always a bad idea because it causes the browser to "serialize" the existing content, then adds to the result string, and then deserialize the entire content again..innerHTML += is bad, see comment above. It works, but its nasty.
creature_nameproperty is an object, not an array, and therefore doesn't have an intrinsiclengthproperty of its own