將結果依日期排序且最新日期在第一筆,也是實務上常見需求,由於 Date 特性,排序時並不像 Number、String 那樣簡單,須自行實作 Comparator Function。
Version
macOS Catalina 10.15.6
Ramda 0.27.1
Date-fp 5.0.3
Wink-fp 1.23.11
sort()
import { sort } from 'ramda'
let data = [
{ title: 'FP in JavaScript', release: '2016-06-18 07:43:14' },
{ title: 'RxJS in Action', release: '2017-08-04 03:24:18' },
{ title: 'Speaking JavaScript', release: '2017-03-24 17:08:39' }
]
sort((x, y) => y.release - x.relase, data) // ?
release
為各書的 發行日期
,我們希望依發行日期 release
排序,且最新日期放在第一筆。
sort()
((a, a) → Number) → [a] → [a]
自行提供 comparator function 將 array 排序
(a, a) -> Number
:自行提供 comparator function 比較
[a]
:data 為 array
[a]
:排序過後新 array
直覺會如處理 number 一樣,將兩數直接相減,但結果不如預期。
發現根本沒有排序。
因為 release
為 string,直接相減為 NaN
,因此排序失敗。
Date-fp
import { sort } from 'ramda'
import { diff } from 'date-fp'
import { toDate } from 'wink-fp'
let data = [
{ title: 'FP in JavaScript', release: '2016-06-18 07:43:14' },
{ title: 'RxJS in Action', release: '2017-08-04 03:24:18' },
{ title: 'Speaking JavaScript', release: '2017-03-24 17:08:39' }
]
// compare :: (a, a) -> Number
let compare = (x, y) => diff('seconds')(
toDate(x.release), toDate(y.release)
)
sort(compare, data) // ?
應該先轉成 Date 之後,再使用 Date-fp 的 diff()
相減排序。
Point-free
import { pipe, sort, useWith, prop } from 'ramda'
import { diff } from 'date-fp'
import { toDate } from 'wink-fp'
let data = [
{ title: 'FP in JavaScript', release: '2016-06-18 07:43:14' },
{ title: 'RxJS in Action', release: '2017-08-04 03:24:18' },
{ title: 'Speaking JavaScript', release: '2017-03-24 17:08:39' }
]
// getDate :: Object -> Date
let getDate = pipe(
prop('release'),
toDate
)
// compare :: (a, a) -> Number
let compare = useWith(
diff('seconds'), [getDate, getDate]
)
sort(compare, data) // ?
也可使用 useWith()
進一步將 compare()
也 point-free。
Conclusion
- Date 格式不能簡單相減,必須轉成 Date 之後使用 Date-fp 的
diff()
相減 - 要將 String 轉成 Date,可使用 Wink-fp 的
toDate()