1
var sorted = results.sort(function (a, b) {
    var nameA = "";
    var nameB = "";
    var str1 = a.date.toLowerCase() + " " + a.time;
    var str2 = b.date.toLowerCase() + " " + b.time;

    if (a.date.toLowerCase() != "" && a.time!= "") 
     nameA = Date.parse(new Date(str1))

    if (b.date.toLowerCase() != "" && b.time!= "") 
     nameB = Date.parse(new Date(str2))

    return nameA === nameB ? 0 : nameA < nameB ? -1 : 1;

});
  1. 如果我的排序方式有任何错误,任何人都可以改进代码。有没有更好的方法?
  2. 我该如何实现http://underscorejs.org/#sortBy上述排序。
4

2 回答 2

4

代码中的一个主要瓶颈是您在每次排序操作中都重新计算 nameA/nameB。考虑到数组中的每个元素都可能参与多次比较,这是很多不必要的工作。您应该首先使用相同的算法构建排序索引,然后使用它进行排序。您还可以将排序键存储在您排序的同一对象中,这样您就可以检查它是否在这里,如果是,则不要重新计算它。

代码中的另外两件事是绝对不必要的:.toLowerCase与空字符串比较和生成无用Data对象时,Data.parse已经明确指定使用字符串。

我已经做了两个改进排序的版本——一个带有辅助函数(更漂亮,在意识形态上更正确)和内联——可能会在某些 JS 引擎上提供一些额外的加速。它们的运行速度都比原来的快大约 3000 倍:http: //jsperf.com/custom-date-sort

(哦,辅助函数恰好适合您的下划线 sortBy 问题)。

有帮手:

function fill_datetime_ms(obj){
    if (obj.date == "" || obj.time == ""){
        return obj.dateTimeMs = ""
    } else {
        return obj.dateTimeMs = Date.parse(obj.date.toLowerCase() + " " + obj.time)
    }
}

var sorted = results.sort(function (a, b) {
    var nameA = a.dateTimeMs
    var nameB = b.dateTimeMs
    if (!nameA && nameA !== "" && !nameA !== 0){
    nameA = fill_datetime_ms(a)
    }
    if (!nameB && nameB !== "" && !nameB !== 0){
        nameB = fill_datetime_ms(b)
    }

    return nameA === nameB ? 0 : nameA < nameB ? -1 : 1;
});

排队:

var sorted = results.sort(function (a, b) {
    var nameA = a.dateTimeMs
    var nameB = b.dateTimeMs
    if (!nameA && nameA !== "" && !nameA !== 0){
        if (a.date == "" || a.time == ""){
            nameA = a.dateTimeMs = ""
        } else {
            nameA = a.dateTimeMs = Date.parse(a.date.toLowerCase() + " " + a.time)
        }
    }
    if (!nameB && nameB !== "" && !nameB !== 0){
        if (b.date == "" || b.time == ""){
            nameB = b.dateTimeMs = ""
        } else {
            nameB = b.dateTimeMs = Date.parse(b.date.toLowerCase() + " " + b.time)
        }
    }

    return nameA === nameB ? 0 : nameA < nameB ? -1 : 1;
});
于 2012-05-25T11:28:43.907 回答
0

最好的办法是让你的 a 和 b 对象从一开始就已经计算好了。比您只需循环而无需处理它。或者按照奥列格所说的存储它。

于 2012-05-25T12:02:11.520 回答