21

Is there a way to get the name of the first property of a JSON object?

I'd like to do something like this:

var firstProp = jsonObj[0];

edit: I'm getting a JSON object which hold categories of arrays with image URLs.

like so:

{
  "category1":["image/url/1.jpg","image/url/2.jpg"],
  "category2":["image/url/3.jpg","image/url/4.jpg"]
}

I am then iterating through the object to insert the images, and all I really wanted was an elegant way to see which category was inserted first. At first I just did

for (var cat in images) {
    if (i==0) firstCat = cat;
    ...
}

But that some how "felt" ugly... So it was basically just a question of elegance.

Jason Aller
  • 3,391
  • 28
  • 37
  • 36
peirix
  • 32,055
  • 22
  • 90
  • 125

5 Answers5

38
console.log(jsonObj[Object.keys(jsonObj)[0]]);
  • 1
    It would be better to write a small explanation of why this is the answer, and why yours is better than the others. – Brian Tompsett - 汤莱恩 May 10 '15 at 16:06
  • 1
    As I understand it, Object.keys(jsonObj) will create an array of the keys of the object which can be accessed using [] notation. [0] is the first item in the array. Adding this as the key lookup for the jsonObject (inside its own square brackets) is essentially saying this; "make an array of all the keys in the object, give me the first of these, now look up the values for that key, in the original object". – Squidinker Oct 08 '16 at 22:16
  • I actually like this one better – Rikku121 Jan 11 '17 at 19:52
34

The order of the properties of an object are not guaranteed to be the same as the way you put them in. In practice, however, all major browsers do return them in order. So if you're okay with relying on this...

var firstProp;
for(var key in jsonObj) {
    if(jsonObj.hasOwnProperty(key)) {
        firstProp = jsonObj[key];
        break;
    }
}

Also note that there's a bug in Chrome regarding the ordering, in some edge cases it doesn't order it in the way they were provided. As far as it changing in the future, the chances are actually pretty small as I believe this is becoming part of the standard so if anything support for this will only become official.

All things considered, though, if you really, really, absolutely, positively, want to be sure it's going to be in the right order you need to use an array. Otherwise, the above is fine.

Related question: Elements order - for (… in …) loop in javascript

Community
  • 1
  • 1
Paolo Bergantino
  • 449,396
  • 76
  • 509
  • 431
  • But what if that changes in the future? – the_drow Jul 12 '09 at 19:36
  • 1
    Just a note to say that object property enumeration order didn't make it into the ECMAScript 5 spec, Chrome has stood fast in its behaviour and now other browsers are following suit, so @the_drow's fears were well-founded. – Tim Down Jun 28 '11 at 15:53
14

There isn't a "first" property. The properties of an object are unordered.

You can get whatever one the JS engine decides to provide first with a loop.

function maybe_first_in_object(ob) {
    for (var props in ob) {
        return prop;
    }
}

… but if the order matters, use an array not an object.

Quentin
  • 800,325
  • 104
  • 1,079
  • 1,205
  • 1
    Good point that they're not guaranteed to be the order you specified them in -- upvoted. I would make sure to check hasOwnProperty() though. – Aseem Kishore Jul 12 '09 at 19:34
2

Great question. I don't know of any way besides iterating in a for-in loop. You only need to iterate once though. For safety, ensure it's a known property [more info].

for (var propName in jsonObj) {
    if (jsonObj.hasOwnProperty(propName)) {
        return propName;    // or do something with it and break
    }
}

Edited to be extra clear that you're iterating over the property names, not their values.

Aseem Kishore
  • 9,137
  • 8
  • 44
  • 55
1

When using jQuery, you can also use $.each to iterate over a JSON object. Looks cleaner IMO than using a for-loop

var items = {
    'item1': 'content',
    'item2': 'content',
    'item3': 'content'
}

$.each(items, function() { 
    console.log($(this)[0])
})
Jeffrey Roosendaal
  • 5,961
  • 8
  • 33
  • 50