對於一般需求,uniq()
即可勝任,但若需經過 Function 轉換後才比較,則要使用 uniqBy()
,自行傳入 Callback。
Version
macOS Catalina 10.15.4
VS Code 1.44.0
Quokka 1.0.285
Ramda 0.27.0
Functional
import { uniqBy, identity } from 'ramda'
let data = [1, 2, 3, 1]
let f = uniqBy(identity)
f(data) // ?
data
很明顯 1
是重複的,我們希望結果只顯示 [1, 2, 3]
。
若我們不知道 uniq()
,也可以使用 uniqBy()
與 identity()
組合而成。
uniqBy()
(a -> b) -> [a] -> [a]
將 array 經過 supply function 轉換,回傳 element 不重複 array
a -> b
:supply function,先經過轉換後再比較
[a]
:data 為 array
[a]
:回傳 element 不重複 array
事實上 Ramda 的
uniq()
就是由uniqBy(identity)
實現
Ramda
import { uniq } from 'ramda'
let data = [1, 2, 3, 1]
let f = uniq
f(data) // ?
事實上 Ramda 已經提供 uniq()
,可直接使用。
uniq()
[a] -> [a]
回傳 element 不重複 array
Primitive
import { uniqBy } from 'ramda'
let data = [1, 2, 3, -1]
let f = uniqBy(x => Math.abs(x))
f(data) // ?
若 1
與 -1
視為相同,我們希望結果只顯示 [1, 2, 3]
。
此時就不能再使用 uniq()
,因為條件太特殊,只能使用 uniqBy()
。
第 5 行
let f = uniqBy(x => Math.abs(x))
自行提供 x => Math.abs(x)
,如此 1
與 -1
都視為相同。
Object
import { uniqBy } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
{ title: 'FP in JavaScript', price: 400 }
]
let f = uniqBy(x => x.title)
f(data) // ?
若 element 為 object,只要 title
相同就視為相同,也就是第一筆與第四筆,雖然 price
不同,但仍視為相同,我們希望結果只顯示不重複的前三筆。
此時就不能再使用 uniq()
,因為條件太特殊,只能使用 uniqBy()
。
10 行
let f = uniqBy(x => x.title)
自行提供 x => x.title
,如此 object 只要 title
相同就視為相同。
Point-free
import { uniqBy, prop } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
{ title: 'FP in JavaScript', price: 400 }
]
let f = uniqBy(prop('title'))
f(data) // ?
x => x.title
也可由 prop()
產生使其 point-free,可讀性更高。
Conclusion
uniq()
也可使用uniqBy(identity)
組合而成uniq()
可視為簡易版;而uniqBy()
為進階版uniq()
- 若只根據 object 特定 property 判斷 unique 條件,則要使用
uniqBy()