3

I have an obejct of the form:

var test = {"2011":{"10":4,"9":9,"8":15,"7":11,"6":11,"5":13,"4":9,"3":5,"2":9,"1":4,"0":20},"2010":{"11":9,"10":23,"9":58}}

I want to iterate over this so I can hit each year and month combo. I have:

var years = d3.keys(test),
    months = d3.range(12),
    data = [];

So, as a Javascript newbie, to sanity check things I inspect years.

document.writeln(years)
2011,2010 

Cool, but when I try to iterate over the years array to pull data out of test the elements I do what I think is correct to test, but the elements are lost:

for(var y in years) {
  document.writeln(y);
}
0,1

How do I iterate over years to get the actual elements (2011,2010) in them?

ZachB
  • 13,051
  • 4
  • 61
  • 89
DrewConway
  • 5,407
  • 7
  • 35
  • 32
  • 2
    I see no JSON, which is a text-based data interchange format, here. And please prefer the term "object" over "[associative] array" to avoid dangerous confusion. – Lightness Races in Orbit Dec 05 '11 at 17:17
  • Use console.log or an actual debugger instead of document.write. Also. for $diety's sake, someone write an answer that doesn't incentivize using for-in to loop in an array. – hugomg Dec 05 '11 at 17:24
  • Where is the array? I don't see one. – Anurag Dec 05 '11 at 17:27
  • I know it's technically correct to do so, but if I see one more comment like "that's not JSON, that's an object", or something similar, I may just have to stick a knife in something – danimal Jun 17 '16 at 17:28

4 Answers4

2

for in retrieves indices/keys (not the values).

You'll need to modify your loop, like so:

for(var y in years) {
  document.writeln(years[y]);
}

EDIT - per missingno's comment, iterating over an array using for in is a bad idea.

for(var i = 0, l = years.length; i < l; i++) {
  document.writeln(years[i]);
}

A little extra information... if you use a for/in loop against an object it will also iterate over your property keys. For example,

for(var y in test) {
  //This will yield, "2011" and then "2010"
  document.writeln(y);
}
Community
  • 1
  • 1
John Strickler
  • 25,151
  • 4
  • 52
  • 68
  • Is there a way to just access the elements with reference the array, like I would with for-loop over an iterator in Python? – DrewConway Dec 05 '11 at 17:23
  • @DrewConway what you are looking for is [`for each`](https://developer.mozilla.org/en/JavaScript/Reference/Statements/for_each...in) for iterating over object property values, but it's non-standard and not widely available. If you want to iterate over arrays, then check out [`forEach`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach). – Anurag Dec 05 '11 at 17:32
  • I personally recommend [underscore.js](http://documentcloud.github.com/underscore/) as a bridge for functions like `forEach` that aren't widely supported yet. – John Strickler Dec 05 '11 at 17:34
2

In javascript for in loops don't do what you think they do; they give you the keys, not the elements

You want

for(var y in years) {
  document.writeln(years[y]);
}

Since you're getting 0,1 back, it looks like years is an actual array, so you could also simply do

for(var i = 0; i < years.length; i++) {
    document.writeln(years[i]);
}

Also, you already edited your title, but a note on terminology. If it's a string, then it's JSON. If it's an object, then, well, it's an object. There's no such thing as a "json object" or "json array"

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
2

AFAIK, var y in years will give you the keys to the array years. years[y] should give you the actual value.

Alec
  • 197
  • 3
  • 10
2

y will end up being the index by which you access the elements in years which is 0 and 1 (because years is an array). So for accessing the values of years, try using

writeln(years[y])

instead of

writeln(y)

(IMHO, Javascript is a bit counter intuitive by working this way)

IllvilJa
  • 228
  • 3
  • 10