4

I have a dynamic array created like this:

window.IDarray = [];

And I have a dictionary created like this:

window.itemdictionary = {};

The length of window.IDarray is the same as window.itemdictionary. And the values of window.IDarray are unique. Also the values of window.IDarray are the keys to the window.itemdictionary.

The datatype of the "value" of any key in window.itemdictionary is also a dictionary that contains a key called "modified" and the value is a string date of the format example "Mon May 28 11:20:46 EDT 2012".

What is the best way to sort the values of window.IDarray, so that going from index 0 to the end of window.IDarray, its corresponding dates in window.itemdictionary are getting farther from the current date? (i.e. index 0 will give closest date to the current date, and index n will give the date farthest away).

2
  • My answer assumes you just want to sort the dates chronologically, not say yesterday is closer to today than two days from now is but tomorrow is closer to today than two days ago. If that's wrong, you'll need to adjust the function to do absolute value math on the difference between new Date() and date_a and date_b and then compare the differences for the result of your comparator function. Commented May 29, 2013 at 19:38
  • please give sample data to get an appropriate solution Commented May 29, 2013 at 19:54

3 Answers 3

3

You will need to use a custom sort function, see Array.sort from MDN.

First, in order to sort by a date, your "modified": "Mon May 28 11:20:46 EDT 2012" needs to be converted to a format that can be used for comparisons, using Date.parse().

var tempItemDictionary = [];   // use temp array to hold the timestamp
// convert dates first
for (var i = 0, item = null; i < IDarray.length; i++) {
    item = itemDictionary[IDarray[i]];
    tempItemDictionary[IDarray[i]] = {
        timestamp: Date.parse(item.modified)    // convert date to timestamp
    };
}

Then we run the IDarray through .sort() using the custom sorting function:

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

See working example: http://jsfiddle.net/788bs/1/

Sign up to request clarification or add additional context in comments.

4 Comments

It would be better to do the conversion in custom sorting function to avoid modifying the original data.
@tracevipin Yes, can use another array to hold the timestamp and sort that. It also depends if that timestamp data will be used again later on.
Agree. If timestamp will be needed again it is better to save it. Depends on the requirement.
@tracevipin I like your suggestion, I have updated the code to use a temporary array to hold the timestamp for sorting, this way the original data in itemDictionary is untouched.
1

Sort the array with a custom comparator function parameter like:

IDarray.sort(function(a, b) {
    var date_a, date_b;
    try {
        date_a = Date.parse(itemdictionary[a]['modified'];
        date_b = Date.parse(itemdictionary[b]['modified'];
        return date_a - date_b;
    } catch (e) {
        /* Some smart exception handling for malformed strings? */
    }
});

2 Comments

Probably not a good idea to call Date.parse every time a comparison is made, for large sets you're going to be doing n^2 conversions of dates :( Along the same lines of performance, you don't want to use try catch inside your comparison function because each time it goes into the try block, the scope chain is augmented so that it can do the catch later when something bad happens. Might be better using if conditions.
Agreed about try…catch but there's no way around the Date.parse thing since that's how the sort is required. I agree it's going to be pretty slow regardless…
0
window.IDarray = [];
window.itemdictionary = {
    "key0": { modified: "Mon May 28 11:20:46 EDT 2012" },
    "key1": { modified: "Mon May 28 11:20:46 EDT 2012" },
    "key2": { modified: "Mon Sep 20 20:35:15 EDT 2010" },
    "key3": { modified: "Mon May 10 10:07:16 EDT 2010" },
    "key4": { modified: "Tue May 10 10:07:16 EDT 2011" }
};

var sortByDate = function(key1, key2) {
    var date1 = new Date(window.itemdictionary[key1].modified.toString());
    var date2 = new Date(window.itemdictionary[key2].modified.toString());
    return date2 - date1;
};
// lt IE9
if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
        var len = this.length >>> 0;
        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
          from += len;

        for (; from < len; from++) {
          if (from in this && this[from] === elt)
            return from;
        }
        return -1;
    };
}

window.itemdictionary.currDate = { modified: new Date().toString() };
window.IDarray = Object.keys(window.itemdictionary);
console.log('before', window.IDarray);
window.IDarray.sort(sortByDate);

delete window.itemdictionary.currDate;
window.IDarray.splice(window.IDarray.indexOf('currDate'), 1);
console.log('after', window.IDarray);

http://jsfiddle.net/nYWmZ/1/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.