2017-04-10 107 views
0

我正在尝试通过一个项目尝试删除本地JS完成工作的地方不必要的第三方依赖项。我们使用Underscore的_.sortBy对日期数组进行排序,但出于某种原因,我无法完全重复确切的排序顺序。自定义日期范围排序

数据回来无序,看起来像这样:

{ 
    "title": "February 2016", 
    "startTime": "2016-02-01T10:00:00.000Z", 
    "endTime": "2016-03-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of February 28 2016", 
    "startTime": "2016-02-28T05:00:00.000Z", 
    "endTime": "2016-03-06T04:59:59.000Z" 
    }, 
    { 
    "title": "March 2016", 
    "startTime": "2016-03-01T10:00:00.000Z", 
    "endTime": "2016-04-01T07:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 06 2016", 
    "startTime": "2016-03-06T05:00:00.000Z", 
    "endTime": "2016-03-13T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 13 2016", 
    "startTime": "2016-03-13T05:00:00.000Z", 
    "endTime": "2016-03-20T03:59:59.000Z" 
    }, 

基本上它只是需要标准的日期排序,除“的一周......”范围整月范围之前应该出现

这是它是如何使用下划线& MomentJS(也使用打字稿),这个正确的排序,我们究竟要如何目前做:

_.sortBy(dateRanges, (range: IDateRange) => { 
    if (moment(range.endTime).diff(range.startTime, "days") > 7) { 
    return range.endTime; 
    } else { 
    return range.startTime; 
    } 
}); 

我试图复制,准确的输出,但没有使用下划线或MomentJS。这是我到目前为止:

dateRanges.sort((r1: IDateRange, r2: IDateRange) => { 
    //604800000 milliseconds in 1 week 
    //easier to hard code number this than do all the math on each iteration here 
    const isWholeMonth = r1.endTime.getTime() - r1.startTime.getTime() > 604800000; 

    if (isWholeMonth) { 
    if (r1.endTime > r2.endTime) { 
     return 1; 
    } else if (r1.endTime < r2.endTime) { 
     return -1; 
    } 
    return 0; 
    } else { 
    //Make the week listings for a month appear before the entire month listings 
    if (r1.startTime > r2.startTime) { 
     return 1; 
    } else if (r1.startTime < r2.startTime) { 
     return -1; 
    } 
    return 0; 
    } 
}); 

它尚未完全排序正确,但我不明白为什么。下面是这两个不同地比本地sort输出到控制台,这样的
http://codepen.io/chrismbarr/pen/KWOaaE

回答

1

下划线的_sortBy工程工作演示。你需要检查和比较不同的情况,如果你有'week'出现在标题或没有(或检查开始时间和结束时间,由你):

interface IDateRange { 
    title: string; 
    startTime: Date; 
    endTime: Date; 
} 

const dateRanges: IDateRange[] = [ 
    { 
    "title": "February 2016", 
    "startTime": "2016-02-01T10:00:00.000Z", 
    "endTime": "2016-03-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of February 28 2016", 
    "startTime": "2016-02-28T05:00:00.000Z", 
    "endTime": "2016-03-06T04:59:59.000Z" 
    }, 
    { 
    "title": "March 2016", 
    "startTime": "2016-03-01T10:00:00.000Z", 
    "endTime": "2016-04-01T07:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 06 2016", 
    "startTime": "2016-03-06T05:00:00.000Z", 
    "endTime": "2016-03-13T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 13 2016", 
    "startTime": "2016-03-13T05:00:00.000Z", 
    "endTime": "2016-03-20T03:59:59.000Z" 
    }, 
    { 
    "title": "October 2016", 
    "startTime": "2016-10-01T08:00:00.000Z", 
    "endTime": "2016-11-01T07:59:59.000Z" 
    }, 
    { 
    "title": "Week of October 02 2016", 
    "startTime": "2016-10-02T04:00:00.000Z", 
    "endTime": "2016-10-09T03:59:59.000Z" 
    }, 
    { 
    "title": "Week of October 30 2016", 
    "startTime": "2016-10-30T04:00:00.000Z", 
    "endTime": "2016-11-06T03:59:59.000Z" 
    }, 
    { 
    "title": "November 2016", 
    "startTime": "2016-11-01T08:00:00.000Z", 
    "endTime": "2016-12-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of November 13 2016", 
    "startTime": "2016-11-13T05:00:00.000Z", 
    "endTime": "2016-11-20T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of November 20 2016", 
    "startTime": "2016-11-20T05:00:00.000Z", 
    "endTime": "2016-11-27T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of November 27 2016", 
    "startTime": "2016-11-27T05:00:00.000Z", 
    "endTime": "2016-12-04T04:59:59.000Z" 
    }, 
    { 
    "title": "December 2016", 
    "startTime": "2016-12-01T10:00:00.000Z", 
    "endTime": "2017-01-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of December 04 2016", 
    "startTime": "2016-12-04T05:00:00.000Z", 
    "endTime": "2016-12-11T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of December 11 2016", 
    "startTime": "2016-12-11T05:00:00.000Z", 
    "endTime": "2016-12-18T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of December 25 2016", 
    "startTime": "2016-12-25T05:00:00.000Z", 
    "endTime": "2017-01-01T04:59:59.000Z" 
    }, 
    { 
    "title": "January 2017", 
    "startTime": "2017-01-01T10:00:00.000Z", 
    "endTime": "2017-02-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of January 15 2017", 
    "startTime": "2017-01-15T05:00:00.000Z", 
    "endTime": "2017-01-22T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of January 29 2017", 
    "startTime": "2017-01-29T05:00:00.000Z", 
    "endTime": "2017-02-05T04:59:59.000Z" 
    }, 
    { 
    "title": "February 2017", 
    "startTime": "2017-02-01T10:00:00.000Z", 
    "endTime": "2017-03-01T09:59:59.000Z" 
    }, 
    { 
    "title": "Week of February 05 2017", 
    "startTime": "2017-02-05T05:00:00.000Z", 
    "endTime": "2017-02-12T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of February 12 2017", 
    "startTime": "2017-02-12T05:00:00.000Z", 
    "endTime": "2017-02-19T04:59:59.000Z" 
    }, 
    { 
    "title": "March 2017", 
    "startTime": "2017-03-01T10:00:00.000Z", 
    "endTime": "2017-04-01T07:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 05 2017", 
    "startTime": "2017-03-05T05:00:00.000Z", 
    "endTime": "2017-03-12T04:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 12 2017", 
    "startTime": "2017-03-12T05:00:00.000Z", 
    "endTime": "2017-03-19T03:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 19 2017", 
    "startTime": "2017-03-19T04:00:00.000Z", 
    "endTime": "2017-03-26T03:59:59.000Z" 
    }, 
    { 
    "title": "Week of March 26 2017", 
    "startTime": "2017-03-26T04:00:00.000Z", 
    "endTime": "2017-04-02T03:59:59.000Z" 
    } 
]; 

////============================== 

console.clear(); 

//Convert to real data objects... 
for (const range of dateRanges) { 
    range.startTime = moment(range.startTime).utc().toDate(); 
    range.endTime = moment(range.endTime).utc().toDate(); 
} 


//OLD 
const librarySort = _.sortBy(dateRanges, (range: IDateRange) => { 
    if (moment(range.endTime).diff(range.startTime, "days") > 7) { 
    return range.endTime; 
    } else { 
    return range.startTime; 
    } 
}); 

//NEW - changes made here 
const nativeSort = dateRanges.sort((r1: IDateRange, r2: IDateRange) => { 
    let firstPartToCompare; 
    let secondPartToCompare; 

    if(r1.title.indexOf('eek') > -1) { 
    firstPartToCompare = r1.startTime; 
    } else { 
    firstPartToCompare = r1.endTime; 
    } 

    if(r2.title.indexOf('eek') > -1) { 
    secondPartToCompare = r2.startTime; 
    } else { 
    secondPartToCompare = r2.endTime; 
    } 

    if (firstPartToCompare > secondPartToCompare) { 
    return 1; 
    } else if (firstPartToCompare < secondPartToCompare) { 
    return -1; 
    } 
    return 0; 
}); 

console.info("CORRECT order - old way") 
console.table(librarySort); 

console.info("ATTEMPT to duplicate - new way") 
console.table(nativeSort); 

http://codepen.io/anon/pen/GWVrwB

+1

使用带'字符串比较>'这将是词典是日期不好的主意。使用'.valueOf()'获取数值纪元时间值并按此进行排序。请务必首先转换为UTC。 –

+0

非常感谢,这就是诀窍。我知道我在做一些简单的事情。以下是我为改变日期而不是使用单词“week”的基础: 'const r1IsWholeMonth = r1.endTime.getTime() - r1.startTime.getTime()> 604800000 ; const firstPartToCompare = r1IsWholeMonth? r1.endTime:r1.startTime;' –

+1

@ChrisBarr没有问题,对我来说已经很晚了,所以我想保持简单。比较时差也是很好的方法,同时考虑到Aluan的评论。 – Oskar