4

In my Javascript application I have an Object and I need to be able to order the array by a value within the Inner Object.

For example:

{
    a : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    b : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    c : {
        timestamp: xxxxxx
        other : yyyyyy
    }
}

What I need to do is manage this data set and re-order the array according to the timestamp of each inner object.

What ways are they that I can do to do this?

update:

My initial thought would be doing something like so:

{
    a : {},
    b : {},
    c : {},
    _ : [
        c, a, b //Key's Only
    ]
}

Then re-indexing the the object based on those values, that would sort out how to index the object, but when I insert a new element i would also have to regenerate the _ index relationship which seems way to much effort.

jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
RobertPitt
  • 56,863
  • 21
  • 114
  • 161

5 Answers5

6

You can copy the data to an array and then sort it:

var data = {
    a : {
        timestamp: 11111,
        other : "xxx"
    },
    b : {
        timestamp: 22222,
        other : "yyy"
    },
    c : {
        timestamp: 33333,
        other : "zzz"
    }
};

var output = [];

// copy items to an array so they can be sorted
for (var key in data) {
    data[key].key = key;   // save key so you can access it from the array (will modify original data)
    output.push(data[key]);
}    

output.sort(function(a,b) {
    return(a.timestamp - b.timestamp);
});

Generates this as output (note I added the original key to the object so it's accessible from the array):

[{"timestamp":11111,"other":"xxx","key":"a"},
{"timestamp":22222,"other":"yyy","key":"b"},
{"timestamp":33333,"other":"zzz","key":"c"}]

You can see this working here: http://jsfiddle.net/jfriend00/hXpkP/

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Don't forget a *hasOwnProperty* test for object properties or you may include inhertied properties. – RobG Sep 14 '11 at 03:14
2

Javascript objects are not associative arrays. They may behave similarly, but they are not the same. Javascript has no associative arrays.

While associative arrays have a concept of order, Javascript objects simply do not share this particular feature with them. Objects, by there very nature, are not ordered.

So, to answer your question: you cannot order them...

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • 1
    Sure, objects don't have order, but that doesn't mean there isn't a possible solution. – jondavidjohn Sep 14 '11 at 13:44
  • you can create an index , hashtable of key values and "order", and when needed use the reference from one array to the object – Miguel Feb 13 '17 at 11:40
2

you are not dealing with an array, but an object with property values of a, b, and c

there is no reason you would need them in a specific order, as you can't really loop over them in any particular order.

this would be trivial (using sort) if you were working with an array...

var array = [
    {
        timestamp: xxxxxx
        other : yyyyyy
    },
    {
        timestamp: xxxxxx
        other : yyyyyy
    },
    {
        timestamp: xxxxxx
        other : yyyyyy
    }
];

array.sort(function(a,b) {
    return a.timestamp - b.timestamp;
});
jondavidjohn
  • 61,812
  • 21
  • 118
  • 158
  • The problems with arrays is that they do not have string based indexes, and to have fast access to elements in need string based indexes. – RobertPitt Sep 14 '11 at 01:19
  • all javascript indexes ***are*** strings and javascript arrays ***are*** objects, they just have a few extra useful features... one you are specifically after... http://jsfiddle.net/Mb8xC/ – jondavidjohn Sep 14 '11 at 05:05
2

As the others have already said, you are dealing with an associative object. Not an array. Objects don't have order.

If you wish to keep it as-is, and sort an array of the keys instead, you can do this:

var obj = {
    a : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    b : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    c : {
        timestamp: xxxxxx
        other : yyyyyy
    }
};

var keys = [];
for(var key in obj) {
    keys.push(key);
}

keys.sort(function(a, b) {
    return obj[a].timestamp - obj[b].timestamp;
});

Now you can access the object via the array values (e.g. obj[keys[0]], obj[keys[1]], etc). This assumes timestamps are numeric. If they are date objects the sort should be:

keys.sort(function(a, b) {
    return +obj[a].timestamp - (+obj[b].timestamp);
});

If the timestamps are actually strings representing a date time (like 'August 2, 2012'), then it should be:

keys.sort(function(a, b) {
    return +new Date(obj[a].timestamp) - (+new Date(obj[b].timestamp));
});

So use whatever makes most sense in your scenario.

Marshall
  • 4,716
  • 1
  • 19
  • 14
0

You could create a custom comparer function and use the built-in sort function for arrays. See this post.

Community
  • 1
  • 1
Annie Lagang
  • 3,185
  • 1
  • 29
  • 36