我有一个基于枢轴命令日期的功能。请注意,此函数忽略提供日期的年份。例如,如果截止日期为1月7日,则所有日期将从7月1日到3月31日订购。问题似乎在于我的排序比较功能,它在Chrome和Firefox中完美运行,但在IE中却失败了。生成的statsDataPoints(Array)不会被排序。
这就是日期数组的样子:
[{"Min":"6.0", "Mean":"10.8", "Max":"32.1", "StdDev":"7.5", "LowerPercentile":"6.7", "Median":"8.0", "UpperPercentile":"11.2", "_Name":"30-Mar"}, {"Min":"6.0", "Mean":"11.1", "Max":"31.7", "StdDev":"7.4", "LowerPercentile":"7.3", "Median":"8.7", "UpperPercentile":"11.1", "_Name":"31-Mar"}, {"Min":"6.0", "Mean":"10.9", "Max":"31.4", "StdDev":"7.3", "LowerPercentile":"7.2", "Median":"8.4", "UpperPercentile":"11.0", "_Name":" 1-Apr"}, ... ]
这是我的功能:
/**
* Returns a function which orders dates based on a pivot. Note that this function ignores the year of the
* supplied dates. It is easiest to illustrate how this function works with an example:
* Given a pivot date of 1-July, all dates will be ordered from 1-July to 31-June.
*
* @param {Array} dates An array of objects containing a date key.
* @param {String} pivot The pivot date we are sorting from (should be in the same format as dateKey)
*/
var dummyYear = 2000;
var pivot = moment(readingStartDate).format("DD-MMM");
pivot = moment(pivot, "DD-MMM").year(dummyYear);
statsDataPoints.sort(function(aDate, bDate) {
var a = moment(aDate["_Name"], "DD-MMM").year(dummyYear).toDate();
var b = moment(bDate["_Name"], "DD-MMM").year(dummyYear).toDate();
if (((a < pivot) && (pivot < b)) || (a > b)) {
return 1;
} else if (((b < pivot) && (pivot < a)) || (a < b)) {
return -1;
}
return 0;
});
答案 0 :(得分:0)
您的比较函数为inconsistent:假设x=1
,y=3
和pivot=2
您获得compare(x, y) == 1
,但compare(y, x) == 1
因为{||
1}}在第一个条件下。
我怀疑你打算使用
if ((a < pivot) && (pivot < b))
return 1;
if ((b < pivot) && (pivot < a))
return -1;
if (a > b) {
return 1;
if (a < b)
return -1;
return 0;
答案 1 :(得分:0)
感谢@CBroe,@ yBrodsky和@Bergi的回复。我设法通过简化我的代码来解决这个问题,而不是使用排序,这很不幸,但是IE并没有真正处理排序比较功能。
鉴于我的数据系列顺序正确,我只是简单地将数据点移到数组的末尾,以确保我的系列在当前日期开始。
为了澄清这一点,我就是这样做的:
// shift series by number of days since start of the year
var startOfYeat = moment().startOf('year');
var curDate = moment();
var daysSinceStartOfYear = curDate.diff(startOfYeat, 'days');
for (i = 0; i < daysSinceStartOfYear; i++) {
statsDataPoints.push(statsDataPoints.shift());
}
&#13;
令人遗憾的是IE似乎并不支持简单的比较功能,所以如果有人对IE中的排序失败有其他想法,请在此处留言。
答案 2 :(得分:0)
问题是您的排序算法对日期传递给它的顺序很敏感。 IE使用不同的排序算法,因此以不同的顺序获取源数据到Firefox,因此有时您会得到不同的结果,有时您不会,这取决于原始数组中日期的顺序。
所以不是IE的错,你应该感谢它有助于识别算法的问题。 ; - )
您的代码中还存在其他一些缺陷。如果您按照moment.js提供的错误消息,您将看到以下行:
var pivot = moment(readingStartDate).format("DD-MMM");
发出警告:
弃用警告:提供的值不在公认的RFC2822或 ISO格式。时刻构造回落到js Date(),这不是 所有浏览器和版本都可靠。非RFC2822 / ISO日期 不鼓励格式,将在即将到来的专业中删除 发布。请参阅 http://momentjs.com/guides/#/warnings/js-date/了解更多信息。 参数:[0] _isAMomentObject:true,_isUTC:false,_useUTC:false, _l:undefined,_ i:31-Mar,_f:undefined,_strict:undefined,_locale:[object Object] undefined
将该行更改为:
var pivot = moment(readingStartDate,'DD-MM').format('DD-MMM');
删除警告。另外,在行中:
(a < pivot) && (pivot < b)
您正在将时刻对象( pivot )与Date对象( a 和 b )进行比较。最简单的解决方法是,如果 pivot 也是日期,那么:
var pivot = moment(readingStartDate,'DD-MM').format('DD-MMM').toDate();
您可以在IE 7中运行以下内容,但不幸的是,SO片段甚至不支持IE 10,因此您必须在别处运行它来测试IE。它虽然在Firefox 38中运行。
它表明以不同的顺序传递相同的值会产生不同的结果。
var statsDataPoints1 = [{"_Name": "30-Mar"}, {"_Name": " 1-Apr"}, {"_Name": "31-Mar"}];
var statsDataPoints2 = [{"_Name": "30-Mar"}, {"_Name": "31-Mar"}, {"_Name": " 1-Apr"}];
var readingStartDate = "31-Mar";
var dummyYear = 2000;
var pivot = moment(readingStartDate, 'DD-MM').format("DD-MMM");
pivot = moment(pivot, "DD-MMM").year(dummyYear).toDate();
function doStuff(statsDataPoints) {
statsDataPoints.sort(function(aDate, bDate) {
var a = moment(aDate["_Name"], "DD-MMM").year(dummyYear).toDate();
var b = moment(bDate["_Name"], "DD-MMM").year(dummyYear).toDate();
if (((a < pivot) && (pivot < b)) || (a > b)) {
return 1;
} else if (((b < pivot) && (pivot < a)) || (a < b)) {
return -1;
}
return 0;
});
}
// This source data sequence gives different results in Firefox and IE
doStuff(statsDataPoints1);
for (var i = 0, iLen = statsDataPoints1.length; i < iLen; i++) {
console.log(statsDataPoints1[i]._Name);
};
// Same data values as statsDataPoints1, different sequence
// Result has the same order in Firefox and IE
doStuff(statsDataPoints2);
for (var i = 0, iLen = statsDataPoints2.length; i < iLen; i++) {
console.log(statsDataPoints2[i]._Name);
};
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
&#13;