2

How do I find the last element in a JavaScript object, if by "last" I consider the one with the largest index? I.e. I am receiving an object similar to an array over ajax (as json), but it also has a non-numeric key:

var received = {
   0: 'something',
   1: 'something else',
   2: 'some stuff',
   3: 'some more stuff',
   'crap' : 'this screws the whole thing'
}

If it were a plain array, I would use array.length. Similarly, I can simply iterate element by element to find it.

Is there a better way? If jQuery is needed for the solution, that's also fine.

Lou
  • 4,244
  • 3
  • 33
  • 72
  • 2
    All you can do is look through the keys with `for ... in` or `Object.keys()`. JavaScript doesn't promise any particular ordering of the keys either. – Pointy Nov 11 '12 at 22:22

6 Answers6

3

This works like the codes from zzzzBov and David Müller, but uses library functions do make it much shorter:

Math.max.apply(null, Object.keys(test).filter(isFinite)) // 3

If you have objects with enumerably-extended prototype objects (which is not the case for JSON.parse results) you might want to use Object.getOwnPropertyNames instead.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

This is not an array, it's an object literal. Moreover, the order of items in object literal is not guaranteed to be preserved after creation (although most browsers seem to obey that).

That being said, generally the answer to your question is: you can't. What you can do is iterating over all properties and finding the last one or whichever you are interested in (see: How to Loop through plain JavaScript object with objects as members?). But remember that the order in which the properties are declared does not have to be preserved during iteration.

However, if this was a true array (disregarding the 'crap' key), that's pretty easy:

received = [
 'something',
 'something else',
 'some stuff',
 'some more stuff'
];

var last = received[received.length - 1];
Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • +1 So, in other words, I can only iterate through elements and find the one with the max index? Actually, it's a data row for jQuery DataTables, and that library requires the data to have a "DT_rowId" key which it uses for setting the `id` attribute for the row. So, it works with DataTables, but then fails when I need some additional processing afterwards. – Lou Nov 11 '12 at 22:22
1

With arrays (which are created with [], not {}), the length property is one more than the last index assigned. So:

var a = [];
a[0] = 'something';
a[5] = 'else';
a["foo"] = 'bar';
console.log(a.length);

will print "6", even though there are only two elements of the array and even though the foo property was set to 'bar'. The length property is only affected by numeric indexes.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • +1 Thanks. Unfortunately, associative php arrays which contain a string key get jsonified as objects. – Lou Nov 11 '12 at 22:25
  • @LousyCoder - That's too bad. I suppose you could fix that by creating a JS object from the JSON and then go through all the keys, testing which (if any) are numeric using `isNaN`. Kind of gross, though. – Ted Hopp Nov 11 '12 at 22:29
1
var received = {
   0: 'something',
   2: 'some stuff',
   3: 'some more stuff',
   1: 'something else',
   'crap' : 'this screws the whole thing'
};

var prop,
    max = -1;
for ( prop in received ) {
  if ( Object.prototype.hasOwnProperty.call(received, prop) && !isNaN(prop) ) {
    max = Math.max(max, prop);
  }
}

console.log(max);
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
0

This is of course not the most elegant approach, but you don't have another choice if have to stick to the literal

<script>
var received = {
   0: 'something',
   1: 'something else',
   2: 'some stuff',
   3: 'some more stuff',
   'crap' : 'this screws the whole thing'
};

var max = null;

for (var i in received)
{
    if (received.hasOwnProperty(i) && !isNaN(i))
    {
        if (max == null || i > max)
            max = i;
    }
}

if (max)
    alert(received[max]); //some more stuff
</script>
David Müller
  • 5,291
  • 2
  • 29
  • 33
0

If you want to know which item has the greatest numeric index value, you'd have to iterate over all the keys in the object:

(function () {
    var i,
        o,
        temp;
    o = getYourObject();
    temp = -Infinity; //lowest possible value
    for (i in o) {
        if (o.hasOwnProperty(i) &&
            !isNaN(i) &&
            +i > temp) {
            temp = +i;
        }
    }
    console.log(temp); //this is the key with the greatest numeric value
}());
zzzzBov
  • 174,988
  • 54
  • 320
  • 367