5

I'm creating a playlist system where each song has a unique ID. When you add a song to the playlist array, its index is registered as its ID.

Normally when looping over a javascript array, you grab the length and count up through the index. Is there a way to loop through an array with unused indexes? Is that bad practice for any reason?

c..
  • 1,044
  • 1
  • 9
  • 23
  • All javascript arrays are associative, you don't need to use a count-up index. – Perception Sep 24 '11 at 16:12
  • @Perception: Nonsense. Javascript `Array`s have sequential, numeric indexes. Perhaps you're referring to more general objects. A common error. – Lightness Races in Orbit Sep 24 '11 at 16:16
  • @Perception Really there is no such thing as an Array or Associative Array. All objects are virtually hashtables. the Array object in Javascript just has a few methods to act like an array on the outside. – Jonathan Sep 24 '11 at 16:18
  • A poorly worded comment on my part. I should have described arrays in terms of objects in order to get my point across. @TomalakGeret'kal - just because they can be *referenced* by sequential, numeric indices doesn't mean they actually *have* sequential, numeric indices. – Perception Sep 24 '11 at 16:25
  • @TomalakGeret'kal Consider this: var a = new Array(); a[10] = 1; What is the length of a? – Jonathan Sep 24 '11 at 16:25
  • @Jonathan: You're using an array as an object, and relying on implementation details. The length is officially `0` there. Again, [it's a common error](http://stackoverflow.com/questions/874205/javascript-what-is-the-difference-between-an-array-and-an-object). The correct code is `var a = []; a.push(1);` and this new element has index `0`. – Lightness Races in Orbit Sep 24 '11 at 16:28
  • @Perception: Wrong again. [You're falling into a common trap.](http://stackoverflow.com/questions/874205/javascript-what-is-the-difference-between-an-array-and-an-object) – Lightness Races in Orbit Sep 24 '11 at 16:28
  • I'm sorry @TomalakGeret'kal, but we see on opposite sides of this issue. If Javascript Arrays were proper arrays in the traditional programming sense then I would not be able to index into them using non-integer indices. Coding style is no replacement for coding constraints. – Perception Sep 24 '11 at 16:40
  • @Perception: When you set "elements" on an `Array` object instance without using `.push`, you're merely setting properties of the underlying object. You're not using the `Array` API `.push` so properties like `length` don't work properly. You're _hacking around the functionality_. It's not a syntax error, but it's **not what you intended to do**; numerically-indexed `Array`s are thin wrappers over the more general `Object`s, so Javascript lets you do it, which is why so many people misunderstand Javascript arrays. Read the Q&A I linked you to for more information and examples. – Lightness Races in Orbit Sep 24 '11 at 16:43
  • @TomalakGeret'kal Actually, the length will be updated to 11, and the indices that you have not set values for will return undefined. If you examine the prototype of a, as I defined above, it is using the array prototype and by setting a value at the 11th index, does not arbitrarily add a property to the object. There is not a difference between how I created the array and how you created the array. The bottom line is that we are given an object either way. Array just happens to have some nice functions in its proto that make it "look" like an array. – Jonathan Sep 24 '11 at 16:45
  • @Jonathan: That is _unspecified behaviour_. Javascript does not have `[]` overloading so there is no way that setting an object property this way can automagically alter the value of a separate one. Your definition of "array" is wrong. If you wish to completely ignore the resources I've linked you to, then I can't control that, but please do not spread this misinformation to language newcomers. Good day. – Lightness Races in Orbit Sep 24 '11 at 16:49
  • @TomalakGeret'kal If you look at the link you specified and on through to the link given in the answer, you land here: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array Take a look at the heading "Relationship between length and numerical properties". It seems to be quite clearly specified behavior. – Jonathan Sep 24 '11 at 17:06
  • @TomalakGeret'kal Also, I want to point out that, regardless of whether Javascript has method overloading, this is completely possible. And it is done using the methods available in the Object prototype. Again, the link you lead me too explains the implementation of array and how it does exactly what you just told me it cannot. Why spread this "misinformation", as you put it, around to anyone? – Jonathan Sep 24 '11 at 17:19
  • @Jonathan: Seems there _is_ a connection between `.length` and `[]`, so I was wrong about that. But my initial point that `Array`s have sequential, numeric indexes stands. In fact, that `.length` is automatically increased to "fit" a new, higher integer key only goes to demonstrate that further. – Lightness Races in Orbit Sep 24 '11 at 17:48
  • @Jonathan: Let me know please if there's anything that you disagree with [here](http://kera.name/articles/2011/09/a-brief-introduction-to-javascript-objects-arrays/). – Lightness Races in Orbit Sep 24 '11 at 17:52
  • 1
    @TomalakGeret'kal In retrospect, I wanted to point out that this debate was very helpful for me. I learned a lot about Javascript that I didn't already know. Thanks for "fueling the fire" a bit. – Jonathan Oct 18 '11 at 12:19
  • @TomalakGeret'kal Jonathan is correct here, just missing a couple details, and perhaps a http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf link to the ECMA standard. Page 88 is the important part. Javascript arrays are objects who treat properties [0..2^32] specially, and maintains a property called length. If you assign to an array using a special property, it will increment length appropriately. Completely standard, and implemented the same across all the JS engines. Everything Is A Object (EIAS), Objects are Maps – David Souther Nov 08 '11 at 19:48

4 Answers4

5
var obj = {"123": "Lalala",
           "456": "dum dum"};
for(var i in obj){
    //i = ID
    // obj[i] = "song"
}

Use for(var i in obj) to loop through an object. See the comments above to understand the meaning of this for-statement.

You're talking about Objects, not arrays, by the way:

var array = [7, 5, 9];

An array can be simulated in this way, so that a for(var i=0; i<array_like.length; i++) can be used. Array functions (such as pop) cannot be used on them, unless you define it:

var array_like = {0:7, 1:5, 2:9, length:3};
Rob W
  • 341,306
  • 83
  • 791
  • 678
4

You can access the object's properties one of two ways. Either using a "." such as:

var my prop = obj.property;

Or via bracket notation:

var my prop = obj["property"];

Now, that doesn't really answer your question. So, here are a few ways:

Utilize jQuery's each function:

$.each(obj, function(key, value){
    //Do something with your key and value.
});

Utilize the Javascript for function:

for(var key in obj)
{
    var value = obj[key];
    //Do something with your key and value.
}

Hope that helps!

Jonathan
  • 5,495
  • 4
  • 38
  • 53
  • Thanks. For...in seems to be the way to go. One thing though: using $.each with jquery seems to behave in the same way that using a regular for loop does, in that it will start with 0 and count up through its length. – c.. Sep 24 '11 at 16:39
0

You can also do just for each to iterate over properties values only:

var obj = {"key1": "val1",
           "key2": "val2"};

for each(var value in obj) {
    ....
}

But in this case, you are not able to access a property name.

Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
timestopper
  • 440
  • 3
  • 4
  • -1 for the incorrect keyword- it is just for, no "each" needed. – David Souther Nov 08 '11 at 19:50
  • There are two types of for: 'for' -- iterates over indexes, and 'for each' -- iterates over values. But 'for each' is not supported in old version of IE. Why do you think it's incorrect keyword? – timestopper Nov 10 '11 at 09:05
  • `for each` is a Mozilla-specific extension to the language, and provides little to no benefit over the standard `for ... in` syntax available in ECMA and all the current JS engines. – David Souther Nov 10 '11 at 18:12
-1

Assuming your array is in the form:

array['id1'] = 'val1';
array['id2'] = 'val2';
array['id3'] = 'val3';

You can iterate over the values by using:

for (var id in array) {  
  document.write(id + ' – ' + array[id]);
} 
Adrien Hingert
  • 1,416
  • 5
  • 26
  • 51