0

I'm trying to loop through an object, to put some values from the object, into a new array. But I have a really hard time figuring out how to do it.

This is my object:

var vehicles = {
    list:{
        "transport":{ //<-- This is the values I want to put to an array
            name:"transport",
            pixelWidth:31,
            pixelHeight:30,
            pixelOffsetX:15,
            pixelOffsetY:15,
            radius:15,
            speed:15,
            sight:3,
            cost:400,
            hitPoints:100,
            turnSpeed:2,
            spriteImages:[
                {name:"stand",count:1,directions:8}         
            ],
        },
        "harvester":{ //<-- This is the values I want to put to an array
            name:"harvester",
            pixelWidth:21,
            pixelHeight:20,
            pixelOffsetX:10,
            pixelOffsetY:10,
            radius:10,
            speed:10,
            sight:3,
            cost:1600,
            hitPoints:50,
            turnSpeed:2,
            spriteImages:[
                {name:"stand",count:1,directions:8}         
            ],
        },
        "scout-tank":{ //<-- This is the values I want to put to an array
            name:"scout-tank",
            canAttack:true,
            canAttackLand:true,
            canAttackAir:false,
            weaponType:"bullet",
            pixelWidth:21,
            pixelHeight:21,
            pixelOffsetX:10,
            pixelOffsetY:10,
            radius:11,
            speed:20,
            sight:3,
            cost:500,
            hitPoints:50,
            turnSpeed:4,
            spriteImages:[
                {name:"stand",count:1,directions:8}         
            ],
        },
        "heavy-tank":{ //<-- This is the values I want to put to an array
            name:"heavy-tank",
            canAttack:true,
            canAttackLand:true,
            canAttackAir:false,
            weaponType:"cannon-ball",
            pixelWidth:30,
            pixelHeight:30,
            pixelOffsetX:15,
            pixelOffsetY:15,
            radius:13,
            speed:15,
            sight:4,
            cost:1200,
            hitPoints:50,
            turnSpeed:4,
            spriteImages:[
                {name:"stand",count:1,directions:8}         
            ],
        }                       
    }

Reading other post, I have the feeling I should use a for-in loop. The real challenge for me, is to get the right value from my object. I've looked at this post to try and solve it.

I come to a solution looking something like this:

var arr = [];

for (var key in vehicles)
    {
        var obj = vehicle[key];
        for (var prop in obj)
            {
                if(obj.hasOwnProperty(prop))
                {
                    arr.push(prop);
                }
            }
    }

console.log(arr);

But I just get this message from console:

Array[0]length: 0__proto__: Array[0]

I also have a running fiddle here

All help would be highly appreciated.

1
  • 2
    It works, if you fix the typo: vehicle -> vehicles. Commented Nov 20, 2014 at 16:30

2 Answers 2

1

If you just want the ones in vehicles.list:

var arr = Object.keys(vehicles.list);

var vehicles = {
  list:{
    "transport":{ //<-- This is the values I want to put to an array
      name:"transport",
      pixelWidth:31,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:15,
      speed:15,
      sight:3,
      cost:400,
      hitPoints:100,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "harvester":{ //<-- This is the values I want to put to an array
      name:"harvester",
      pixelWidth:21,
      pixelHeight:20,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:10,
      speed:10,
      sight:3,
      cost:1600,
      hitPoints:50,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "scout-tank":{ //<-- This is the values I want to put to an array
      name:"scout-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"bullet",
      pixelWidth:21,
      pixelHeight:21,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:11,
      speed:20,
      sight:3,
      cost:500,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "heavy-tank":{ //<-- This is the values I want to put to an array
      name:"heavy-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"cannon-ball",
      pixelWidth:30,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:13,
      speed:15,
      sight:4,
      cost:1200,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    }    
  }
};
var arr = Object.keys(vehicles.list);
snippet.log(arr.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

If you want all of the keys of the objects referenced by any property of vehicles, then:

var arr = [];
Object.keys(vehicles).forEach(function(key) {
  arr.push.apply(arr, Object.keys(vehicles[key]));
});

The trick there is that we can push an entire array of entries onto arr using arr.push.apply(arr, /*the other array*/).

var vehicles = {
  list:{
    "transport":{ //<-- This is the values I want to put to an array
      name:"transport",
      pixelWidth:31,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:15,
      speed:15,
      sight:3,
      cost:400,
      hitPoints:100,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "harvester":{ //<-- This is the values I want to put to an array
      name:"harvester",
      pixelWidth:21,
      pixelHeight:20,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:10,
      speed:10,
      sight:3,
      cost:1600,
      hitPoints:50,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "scout-tank":{ //<-- This is the values I want to put to an array
      name:"scout-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"bullet",
      pixelWidth:21,
      pixelHeight:21,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:11,
      speed:20,
      sight:3,
      cost:500,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "heavy-tank":{ //<-- This is the values I want to put to an array
      name:"heavy-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"cannon-ball",
      pixelWidth:30,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:13,
      speed:15,
      sight:4,
      cost:1200,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    }    
  },
  list2: {
    "new-key-for-list2":{
      }
  }
};
var arr = [];
Object.keys(vehicles).forEach(function(key) {
  arr.push.apply(arr, Object.keys(vehicles[key]));
});
snippet.log(arr.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Or if you really like one-liners, you could use Array#reduce but I think clarity suffers:

var arr = Object.keys(vehicles).reduce(function(a, key) {
  a.push.apply(a, Object.keys(vehicles[key]));
  return a;
}, []);

var vehicles = {
  list:{
    "transport":{ //<-- This is the values I want to put to an array
      name:"transport",
      pixelWidth:31,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:15,
      speed:15,
      sight:3,
      cost:400,
      hitPoints:100,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "harvester":{ //<-- This is the values I want to put to an array
      name:"harvester",
      pixelWidth:21,
      pixelHeight:20,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:10,
      speed:10,
      sight:3,
      cost:1600,
      hitPoints:50,
      turnSpeed:2,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "scout-tank":{ //<-- This is the values I want to put to an array
      name:"scout-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"bullet",
      pixelWidth:21,
      pixelHeight:21,
      pixelOffsetX:10,
      pixelOffsetY:10,
      radius:11,
      speed:20,
      sight:3,
      cost:500,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    },
    "heavy-tank":{ //<-- This is the values I want to put to an array
      name:"heavy-tank",
      canAttack:true,
      canAttackLand:true,
      canAttackAir:false,
      weaponType:"cannon-ball",
      pixelWidth:30,
      pixelHeight:30,
      pixelOffsetX:15,
      pixelOffsetY:15,
      radius:13,
      speed:15,
      sight:4,
      cost:1200,
      hitPoints:50,
      turnSpeed:4,
      spriteImages:[
        {name:"stand",count:1,directions:8}         
      ],
    }    
  },
  list2: {
    "new-key-for-list2":{
      }
  }
};
var arr = Object.keys(vehicles).reduce(function(a, key) {
  a.push.apply(a, Object.keys(vehicles[key]));
  return a;
}, []);
snippet.log(arr.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


Note that Object.keys and Array#forEach (and Array#reduce) were all added in ES5 (2009-ish), so they're in all modern browsers, but missing from IE8 and other similar old browsers. All three can be polyfilled, though.

Sign up to request clarification or add additional context in comments.

2 Comments

That is much more simple than anything else I've seen and it works. Awesome!! Thanks!
@TommyOtzen: :-) No worries. I forgot to add my usual ES5 note; I've added it above.
1

When iterating with a for in loop you get the key in each iteration. This key should be used to access the value from the original array. In your loop you are accessing a non existing(as far as I can see) variable - vehicle. Change it to the array's name - vehicles:

var arr = [];

for (var key in vehicles)
    {
        var obj = vehicles[key];
        for (var prop in obj)
            {
                if(obj.hasOwnProperty(prop))
                {
                    arr.push(prop);
                }
            }
    }

console.log(arr);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.