【问题标题】:How to sort a dynamic array如何对动态数组进行排序
【发布时间】:2013-05-25 04:44:01
【问题描述】:

我有一个这样创建的动态数组:

window.IDarray = [];

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

window.itemdictionary = {};

window.IDarray 的长度与window.itemdictionary 相同。 window.IDarray 的值是唯一的。 window.IDarray 的值也是 window.itemdictionary 的键。

window.itemdictionary 中任意键的“值”的数据类型也是一个字典,其中包含一个名为"modified" 的键,值是格式示例"Mon May 28 11:20:46 EDT 2012" 的字符串日期。

window.IDarray 的值进行排序的最佳方法是什么,以便从索引0window.IDarray 的末尾,其在window.itemdictionary 中的对应日期离当前日期越来越远? (即索引0 将给出最接近当前日期的日期,而索引n 将给出最远的日期)。

【问题讨论】:

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

标签: javascript jquery arrays date sorting


【解决方案1】:

您将需要使用自定义排序功能,请参阅Array.sort from MDN

首先,为了按日期排序,您的"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/

【讨论】:

  • 最好在自定义排序功能中进行转换,避免修改原始数据。
  • @tracevipin 是的,可以使用另一个数组来保存时间戳并对其进行排序。这还取决于以后是否会再次使用该时间戳数据。
  • 同意。如果再次需要时间戳,最好保存它。视需求而定。
  • @tracevipin 我喜欢你的建议,我已经更新了代码以使用临时数组来保存用于排序的时间戳,这样itemDictionary 中的原始数据就不会受到影响。
【解决方案2】:

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

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 条件可能会更好。
  • 同意try…catch,但没有办法绕过Date.parse,因为这是需要排序的方式。我同意无论如何它都会很慢......
【解决方案3】:
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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-15
    • 2018-10-11
    • 2013-07-21
    • 1970-01-01
    • 2021-09-05
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多