如何对动态数组进行排序

4

我有一个动态数组,创建方式如下:

window.IDarray = [];

我有一个像这样创建的字典:

window.itemdictionary = {};
window.IDarray的长度与window.itemdictionary相同,且window.IDarray的值是唯一的。此外,window.IDarray的值是window.itemdictionary的键。
window.itemdictionary中,任何键的“value”数据类型也是一个字典,其中包含一个名为"modified"的键,其值是格式示例"Mon May 28 11:20:46 EDT 2012"的字符串日期。
如何最好地对window.IDarray的值进行排序,以便从索引0window.IDarray的末尾,其对应的window.itemdictionary中的日期距离当前日期越远越好?(即索引0将给出最接近当前日期的日期,而索引n将给出最远的日期)。

我的回答假设您只想按时间顺序排序日期,而不是说昨天比两天后更接近今天,但明天比两天前更接近今天。如果这样不对,您需要调整函数以在new Date()date_a以及date_b之间的差异上进行绝对值数学运算,然后比较差异以获取比较器函数的结果。 - jxpx777
请提供样本数据以获得适当的解决方案。 - Diode
3个回答

3
你需要使用自定义排序函数,参见MDN中的Array.sort
首先,为了按日期排序,你的"modified": "Mon May 28 11:20:46 EDT 2012"需要转换成可用于比较的格式,使用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
    };
}

然后我们使用自定义排序函数将IDarray传递给.sort()
IDarray.sort(function(a, b) {
    return tempItemDictionary[b].timestamp - tempItemDictionary[a].timestamp;
});

查看工作示例:http://jsfiddle.net/788bs/1/


最好在自定义排序函数中进行转换,以避免修改原始数据。 - Diode
@tracevipin 是的,可以使用另一个数组来保存时间戳并进行排序。这也取决于时间戳数据是否会在以后再次使用。 - Amy
同意。如果时间戳将再次需要,则最好保存它。这取决于具体要求。 - Diode
@tracevipin 我喜欢你的建议,我已经更新了代码并使用了一个临时数组来保存时间戳以进行排序,这样 itemDictionary 中的原始数据就不会被改变。 - Amy

1

使用自定义比较函数参数对数组进行排序,例如:

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? */
    }
});

每次进行比较时调用Date.parse可能不是一个好主意,对于大数据集,你将会做n^2个日期转换:( 同样关于性能,你不想在比较函数内使用try catch,因为每次进入try块时,作用域链都会增加,以便在发生错误时可以执行catch。最好使用if条件。 - Amy
关于 try...catch 我们达成了一致,但是由于排序需要,无法避免使用 Date.parse。我同意这样会导致速度变慢。 - jxpx777

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/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接