1

I have this code to iterate through an array of objects:

for (vehicleIndex in scenes[sceneID].vehicles) {
  vehicleID = scenes[sceneID].vehicles[vehicleIndex];
  ...
}

but I need to know how to determine the number of items being iterated through so that on the final item, I can execute a particular function. How do I do this?

mheavers
  • 26,845
  • 54
  • 181
  • 285

5 Answers5

2

Example in ES5:

Object.keys( scenes[sceneID].vehicles ).forEach(function( vehicle, index, arr ) {
    if( index === arr.length - 1 ) {
        // do something on last entry
    }
});

Even tho, "last" just means the last element which was looped over. Since there is specific order within a Javascript object (they are infact unordered). However, we could sort the object key names manually by just chaining a .sort() before the .forEach()

jAndy
  • 212,463
  • 51
  • 293
  • 348
  • The "default sorting" is also implementation specific as objects are bags of un-ordered keys (hence not associative arrays) – Raynos Aug 22 '11 at 12:51
1
var arraySize = scenes[sceneID].vehicles.length;
var i;
var currentItem;
for (i = 0; i < arraySize; i++) {
  currentItem = scenes[sceneID].vehicles[i];
  if (i == arraySize - 1) {
    // do something special
  } else {
     // do something not so special ;-)
  }
}
βξhrαng
  • 41,698
  • 21
  • 103
  • 145
0

scenes[sceneID].vehicles should have a length property.

gislikonrad
  • 3,121
  • 2
  • 19
  • 22
0

Use this to find the length:

scenes[sceneID].vehicles.length

length is a built-in property in arrays. However, if you want to check for the last item, you have to check

scenes[sceneID].vehicles.length - 1

as arrays are zero-indexed.

Also, you should not use for...in to loop on arrays - if someone extends Array.prototype (or worse, Object.prototype), then you will not be happy. Use a normal for loop (which also allows you to use the final item easily):

var len = scenes[sceneID].vehicles.length;
for (var vehicleIndex = 0; vehicleIndex < len; vehicleIndex++) {
  vehicleID = scenes[sceneID].vehicles[vehicleIndex];
  //...
}
//Do something with the final item here
//Similar to this: itemFunc(vehicleID);

See this SO question for more details.

Community
  • 1
  • 1
Digital Plane
  • 33,886
  • 6
  • 50
  • 58
  • for...in can be used safely if you have an if statement to check if the property belongs to the object in question or it was inherited (.hasOwnProperty()) – jbabey Aug 22 '11 at 13:25
  • @jbabey True. However, the order of iteration is undefined, and the final item cannot be reliably accessed after the loop if you do that: http://stackoverflow.com/questions/280713/elements-order-for-in-loop-in-javascript – Digital Plane Aug 22 '11 at 13:59
0
for (vehicleIndex in scenes[sceneID].vehicles) {
  vehicleID = scenes[sceneID].vehicles[vehicleIndex];
  ...
}
doSomethingWithLastItem(vehicleId);

Because JS does not have block scope, by the time your loop finished vehicleId will be the last item's id.

In generic terms you can get the size of an array by accessing the .length property. You can also get the size of an object using Object.keys(obj).length.

Raynos
  • 156,883
  • 55
  • 337
  • 385