按日期对数组进行排序会产生意想不到的结果 [英] Sort array by date gives unexpected results

查看:23
本文介绍了按日期对数组进行排序会产生意想不到的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这听起来是一个简单的问题,但我花了我的星期天试图找出下面描述的我的实现有什么问题,所以我将它发布到 SO 作为最后的手段.

This will sound as an easy problem but I spent my Sunday trying to figure out what's wrong with my implementation described below so I am posting it to SO as a last resort.

我有一个从服务器接收数据结构的 javascript 应用程序.服务器端出于性能原因发送未排序的数据.

I have a javascript application that receives data structures from a server. The server side sends the data unsorted for performance reasons.

这是接收数据的javascript代码片段:

Here is a snippet of the the javascript code receiving data:

    var seriesRawDataArray = ko.observableArray();
    ...
    analyticscontext.series(seriesRawDataArray).done(function () {
        renderSeries();
    });

analyticscontext 模块使用 ajax 查询数据:

The analyticscontext module queries the data using ajax:

function series(seriesData) {
    return $.ajax({
        url: "/api/analytics/series",
        type: "GET",
        success: function (data) {
            return seriesData(data);
        }
    });
}

renderSeries 在渲染数据之前对数据进行排序:

The renderSeries performs a sort on the data before rendering it:

    // Sort the data by date using moment.js
    seriesRawDataArray.sort(function (left, right) {
        var leftDate = moment.utc(left.timeStamp);
        var rightDate = moment.utc(right.timeStamp);
        var diff = leftDate.diff(rightDate);
        return diff > 0;
    });

问题

这是我从我的服务器收到的数据样本:

Here is a data sample I receive from my server:

注意最后未排序的项目.seriesRawDataArray.sort 似乎对原始数组没有影响,无论我如何更改排序方法,原始数组都不会被排序.输出总是:

Notice the unsorted items at the end. the seriesRawDataArray.sort seem to have no effect on the original array which does not get sorted no matter what I change in the sorting method. The output is always:

注意这里未排序的元素.我正在使用的库和数据绝对不是问题,因为这个 jsfiddle 工作得很好!这段代码有问题吗?

Notice the unsorted elements here. The libraries I am using and the data is definitely not the problem as this jsfiddle works just fine! Is there something wrong with this code?

推荐答案

简答

您应该返回两个日期之间的差异,而不是布尔值:

short answer

You should return the difference between the two dates, not a boolean:

// sort the data by date using moment.js
seriesRawDataArray.sort(function (left, right) {
    return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))
});

为什么

Array.prototype.sort 期望返回负值、零值或正值.一般来说,你会写一个这样的排序函数:

why

Array.prototype.sort expects a negative, zero, or positive value to be returned. Generally, you'll write a sort function like this:

yourArray.sort(function (a, b) {
    if (a < b) {            // a comes first
        return -1
    } else if (b < a) {     // b comes first
        return 1
    } else {                // equal, so order is irrelevant
        return 0            // note: sort is not necessarily stable in JS
    }
})

传递给 sort 的匿名函数用作 sort 函数本机实现的比较器.

但是,负值不一定是 -1,正值不一定是 +1.因此,在对数字进行排序时,您可以改为使用快捷方式:

However, your negative value doesn't have to be -1 and your positive value doesn't have to be +1. Therefore, when sorting numbers, you can instead use the shortcut:

yourArray.sort(function (a, b) {
    return a - b
})

在 JavaScript 中,减去两个日期会将它们强制转换为数字,这就是为什么我们可以使用 return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))

In JavaScript, subtracting two dates coerces them both into numbers, which is why we could use return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))

(代替直接减法-,该方法使用moment.prototype.diff 来自 moment.js 库)

(instead of direct subtraction -, this method uses moment.prototype.diff from the moment.js library)

但是,在您的代码中,您返回了 diff >0,可以是 truefalse.由于类型强制,JavScript 会将 true 读取为 1,将 false 读取为 0.这意味着您的排序函数永远不会返回 -1.因此,您的元素将无法正确排序.

However, in your code, you returned diff > 0, which can be either true or false. Because of type coercion, JavScript will read true as 1 and false as 0. This means your sort function will never return -1. Therefore, your elements will not be sorted correctly.

这篇关于按日期对数组进行排序会产生意想不到的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆