By nkuhta


2013-01-17 12:36:15 8 Comments

I have an object in JavaScript:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

I want to use a for loop to get its properties. And I want to iterate it in parts (not all object properties at once).

With a simple array I can do it with a standard for loop:

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

But how to do it with objects?

13 comments

@Denys Séguret 2013-01-17 12:37:59

For most objects, use for .. in :

for (var key in yourobject) {
  console.log(key, yourobject[key]);
}

With ES6, if you need both keys and values simultaneously, do

for (let [key, value] of Object.entries(yourobject)) {
    console.log(key, value);
}

To avoid logging inherited properties, check with hasOwnProperty :

for (var key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}

This MDN documentation explains more generally how to deal with objects and their properties.

If you want to do it "in chunks", the best is to extract the keys in an array. As the order isn't guaranteed, this is the proper way. In modern browsers, you can use

var keys = Object.keys(yourobject);

To be more compatible, you'd better do this :

 var keys = [];
 for (var key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

Then you can iterate on your properties by index: yourobject[keys[i]] :

for (var i=300; i<keys.length && i<600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

@pawel 2013-01-17 12:39:22

OP wants to perform this in chunks, not all keys in a single loop.

@nkuhta 2013-01-17 12:40:20

Yes. Not full object in one loop.

@Denys Séguret 2013-01-17 12:42:46

@NikitaKuhta Then look at the updated answer.

@Cerbrus 2013-01-17 12:45:25

This does not answer the question on how to iterate through a part of the object.

@Denys Séguret 2013-01-17 12:45:49

@Cerbrus Did you read until the end ?

@Yoshi 2013-01-17 12:47:13

@Cerbrus The OP allready knows how to iterate an array in parts. Using keys from the code given should be enough.

@Cerbrus 2013-01-17 12:48:36

@Yoshi / @dystroy: Object.keys() support is IE 9+. For compatibility purposes, I'd suggest not using that.

@Denys Séguret 2013-01-17 12:49:19

@Cerbrus Please read before commenting ! What's not clear in "To be more compatible, you'd better do this" ?

@Teodor Talov 2013-07-14 05:55:46

+1 for the console.log() instead of alert() / and for providing the link to MDN

@am05mhz 2015-09-10 02:31:45

hi, sorry for bringing old topic, but is there any point of the if (yourobject.hasOwnProperty(key)) ?, as i get the same result with only keys.push(key), and it should be a little faster without the if

@Denys Séguret 2015-09-10 06:21:51

@am05mhz As I said, it's useless with most objects. But not for all. Try this: jsbin.com/hirivubuta/1/edit?js,console,output

@Hamid Asghari 2017-07-13 20:37:42

obj.hasOwnProperty() was needed, thanks

@Derek Soike 2018-09-28 18:11:50

If you want the key and value when iterating, you can use a for...of loop with Object.entries.

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

@Willem van der Veen 2018-09-28 08:09:54

For object iteration we usually use a for..in loop. This structure will loop through all enumerable properties, including ones who are inherited via prototypal inheritance. For example:

let obj = {
  prop1: '1',
  prop2: '2'
}

for(let el in obj) {
  console.log(el);
  console.log(obj[el]);
}

However, for..in will loop over all enumerable elements and this will not able us to split the iteration in chunks. To achieve this we can use the built in Object.keys() function to retrieve all the keys of an object in an array. We then can split up the iteration into multiple for loops and access the properties using the keys array. For example:

let obj = {
  prop1: '1',
  prop2: '2',
  prop3: '3',
  prop4: '4',
};

const keys = Object.keys(obj);
console.log(keys);


for (let i = 0; i < 2; i++) {
  console.log(obj[keys[i]]);
}


for (let i = 2; i < 4; i++) {
  console.log(obj[keys[i]]);
}

@Steven Spungin 2018-04-28 02:14:02

Really a PITA this is not part of standard Javascript.

/**
 * Iterates the keys and values of an object.  Object.keys is used to extract the keys.
 * @param object The object to iterate
 * @param fn (value,key)=>{}
 */
function objectForEach(object, fn) {
    Object.keys(object).forEach(key => {
        fn(object[key],key, object)
    })
}

Note: I switched the callback parameters to (value,key) and added a third object to make the API consistent other APIs.

Use it like this

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
    // do something
});

@CONTRACT SAYS I'M RIGHT 2018-06-12 11:14:41

upvoted just for your statement in the first sentence. Even though it'd be better if the value was first parameter, the index or key second parameter, and the object third parameter, to make it more like the array forEach(). I'd recommend recommending lodash though.

@Steven Spungin 2018-06-12 15:42:57

I do like the idea of the (value, key) order. That is how a library such as Vue does it too. Because the object is the context, it do think it belongs as the first parameter though. That's pretty standard for functional programming.

@CONTRACT SAYS I'M RIGHT 2018-06-12 15:53:30

I would agree here, were it not for ECMA-262 defining an array as an object having a forEach(), map(), reduce(), filter(), which all take callbacks receiving the order [value, index, array]. An object in JS can be understood as just another collection; and then these methods become unified in their parameters of [value, key|index, context] (this is what lodash and underscore are doing). In my opinion, this "unified collection" protocol is just stronger. Also, the object isn't the context: you can set this to whatever you like for the callback, as the callback has its own context.

@Steven Spungin 2018-06-12 17:55:51

Perhaps I should have used the work receiver instead of this. Anyway still a PITA; I would welcome the parameters in any order.

@CONTRACT SAYS I'M RIGHT 2018-06-12 21:25:35

Oh, I see that we might have misunderstood each other. I was always commenting about the callback parameters and their order, not about the actual objectForEach function. Sorry if that was confusing.

@Parth Raval 2018-04-09 06:34:41

You can try using lodash- A modern JavaScript utility library delivering modularity, performance & extras js to fast object iterate:-

var  users  =   {
    'fred':     { 
        'user':   'fred',
            'age':  40 
    },
    'pebbles':  { 
        'user':   'pebbles',
         'age':  1 
    }
}; 
_.mapValues(users,  function(o)  { 
    return  o.age; 
});
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
// The `_.property` iteratee shorthand.
console.log(_.mapValues(users,  'age')); // returns age property & value 
console.log(_.mapValues(users,  'user')); // returns user property & value 
console.log(_.mapValues(users)); // returns all objects 
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>

@Parth Raval 2018-04-18 05:49:57

what's wrong in my answer?

@Alrik Zachert 2018-02-15 23:10:04

I finally came up with a handy utility function with a unified interface to iterate Objects, Strings, Arrays, TypedArrays, Maps, Sets, (any Iterables).

const iterate = require('@a-z/iterate-it');
const obj = { a: 1, b: 2, c: 3 };

iterate(obj, (value, key) => console.log(key, value)); 
// a 1
// b 2
// c 3

https://github.com/alrik/iterate-javascript

@Cerbrus 2013-01-17 12:44:30

The only reliable way to do this would be to save your object data to 2 arrays, one of keys, and one for the data:

var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

You can then iterate over the arrays like you normally would:

for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

I am not using Object.keys(obj), because that's IE 9+.

@Adeel Imran 2018-01-30 06:12:41

Using Object.entries you do something like this.

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

The Object.entries() method returns an array of a given object's own enumerable property [key, value]

So you can iterate over the Object and have key and value for each of the object and get something like this.

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

or like this

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

For a reference have a look at the MDN docs for Object Entries

@ashishdudhat 2017-12-14 05:56:31

->if we iterate over a JavaScript object using and find key of array of objects

Object.keys(Array).forEach(key => {

 console.log('key',key)

})

@Paul 2016-08-04 03:42:06

With the new ES6/ES2015 features, you don't have to use an object anymore to iterate over a hash. You can use a Map. Javascript Maps keep keys in insertion order, meaning you can iterate over them without having to check the hasOwnProperty, which was always really a hack.

Iterate over a map:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

or use forEach:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

@pungggi 2018-06-03 09:59:48

forEach is the prefered one

@HovyTech 2016-07-03 22:51:51

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

@Dodekeract 2017-02-19 12:46:05

Actually no. This implies that Objects are in-order. They're not. If you can make sense of the sentence it worked only works because of implementation details. It's not guaranteed to work at all. Also you shouldn't TitleCase your functions & variables. That's for classes.

@Michał Miszczyszyn 2013-01-17 12:48:13

If you wanted to iterate the whole object at once you could use for in loop:

for (var i in obj) {
  ...
}

But if you want to divide the object into parts in fact you cannot. There's no guarantee that properties in the object are in any specified order. Therefore, I can think of two solutions.

First of them is to "remove" already read properties:

var i = 0;
for (var key in obj) {
    console.log(obj[key]);
    delete obj[key];
    if ( ++i > 300) break;
}

Another solution I can think of is to use Array of Arrays instead of the object:

var obj = [['key1', 'value1'], ['key2', 'value2']];

Then, standard for loop will work.

@VisioN 2013-01-17 12:40:29

Here is another iteration solution for modern browsers:

Object.keys(obj).filter(function(k, i) {
    return i >= 100 && i < 300;
}).forEach(function(k) {
    console.log(obj[k]);
});

Or even shorter:

Object.keys(obj).forEach(function(k, i) {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

However you must consider that properties in JavaScript object are not sorted, i.e. have no order.

@nkuhta 2013-01-17 12:40:56

And how to start next loop from "i" position???

@nkuhta 2013-01-17 12:43:01

If I will break loop, it will start from beginning of object next time, that is not right way.

@VisioN 2013-01-17 14:43:02

@NikitaKuhta I have updated the answer. Now it works fine.

Related Questions

Sponsored Content

29 Answered Questions

[SOLVED] For-each over an array in JavaScript?

38 Answered Questions

[SOLVED] How to efficiently iterate over each entry in a Java Map?

37 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

69 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5306186 View
  • 6612 Score
  • 69 Answer
  • Tags:   javascript arrays

25 Answered Questions

64 Answered Questions

[SOLVED] What is the most efficient way to deep clone an object in JavaScript?

35 Answered Questions

[SOLVED] Length of a JavaScript object

86 Answered Questions

[SOLVED] How do JavaScript closures work?

7 Answered Questions

[SOLVED] Iterate through a HashMap

48 Answered Questions

Sponsored Content