Ramda 的 sort()
與 ECMAScript 內建的 Array.prototype.sort()
非常類似,都需自行提供 Comparator Function,唯 sort()
是無 Side Effect 版本。
Version
macOS Catalina 10.15.6
Ramda 0.27.1
Ramda
import { sort } from 'ramda'
let data = [3, 4, 2, 1]
sort((x, y) => x - y, data) // ?
Ascend 為 sort()
搭配 x - y
;而 descend 為 y - x
。
sort()
((a, a) → Number) → [a] → [a]
將 array 根據 comparator function 加以排序
(a, a) -> Number
:comparator function,若第一個參數比第二個參數小,傳回 < 0
,也就是 ascend;若第一個參數比第二個參數大,傳回 > 0
,也就是 descend,若相等則傳回 = 0
[a]
:data 為 array
[a]
:回傳新 array,型別完全相同,只是順序不同
Q:Ramda 的
sort()
看起來與 ECMAScript 原生的Array.prototype.sort()
似乎一樣 ?
乍看之下似乎一樣,但仍有兩點不同:
Array.prototype.sort()
的 comparator function 可省略,預設為 ascend。Array.prototype.sort()
為 side effect 寫法,會直接更改原本 array;而 Ramda 的sort()
沒有 side effect,會傳回新 array
ascend()
import { sort, ascend } from 'ramda'
let data = [3, 4, 2, 1]
sort(ascend(Number), data) // ?
若常常不知道該 x - y
還是 y - x
,可直接使用 ascend()
與 descend()
產生 comparator function。
ascend()
Ord b => (a → b) → a → a → Number
產生 ascend comparator function
或
descend()
Ord b => (a → b) → a → a → Number
產生 descend comparator function
Object
import { sort } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 300 },
{ title: 'RxJS in Action', price: 400 },
{ title: 'Speaking JavaScript', price: 200 },
{ title: 'JavaScript: The Good Parts', price: 100 },
]
sort((x, y) => y.price - x.price, data) // ?
sort()
提供 comparator function,描述該用什麼 property 做比較。
descend()
import { sort, descend, prop } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 300 },
{ title: 'RxJS in Action', price: 400 },
{ title: 'Speaking JavaScript', price: 200 },
{ title: 'JavaScript: The Good Parts', price: 100 },
]
sort(descend(prop('price')), data) // ?
sort()
的 comparator function,也可改用 ascend()
與 prop()
來組合使之 point-free。
Conclusion
sort()
最接近Array.prototype.sort()
,唯 Ramda 的sort()
不可省略 comparator function,且對原來 Array 無 side effect- 可使用
ascend()
、descend()
、prop()
等產生 callback function 達成 point-free