[JavaScriptでArrayをuniqにする]
(https://qiita.com/oubakiou/items/b848434e65d0644e1dfc)を元に
const defaultComparator = <T>(a: T, b: T): boolean => a === b
export const distinctBy = <T>(
array: Array<T>,
comparator: (a: T, b: T) => boolean = defaultComparator
): Array<T> =>
array.filter(
(elem, index, self) => self.findIndex(e => comparator(elem, e)) === index
)
で
type Dog = {
id: string
name: string
}
const comparator = (a: Dog, b: Dog) => a.id === b.id
const dogsDistinct = (dogs: Array<Dog>) => distinctBy(dogs, comparator)
みたいな。
ところでJavascriptにはビルトインの等価性アルゴリズムが4種類ある(演算子としては3種類ある)のでcomparatorを実装する時はどれに合わせるのか気をつけたほうが良いと思います。
[1, 2] == '1,2' //true
[1, 2] === '1,2' //false
Object.is([1, 2], '1,2') //false
NaN == NaN //false
NaN === NaN //false
Object.is(NaN, NaN) //true
+0 == -0 //true
+0 === -0 //true
Object.is(+0, -0) //false
TypeScriptを使っていると型の上でも馴染みが深い、構造が一致するかどうかという比較はビルトインでは提供されていないため、必要であればdeep-equalのような外部パッケージを利用すると便利です。
see also
- [等価性の比較と同一性 - JavaScript | MDN]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Equality_comparisons_and_sameness) - [等価演算子の同一性 構造の等価性(Structural Equality) - TypeScript Deep Dive 日本語版]
(https://typescript-jp.gitbook.io/deep-dive/recap/equality) - [JavaScriptの等値比較を全部理解する]
(https://qiita.com/uhyo/items/d99f536332e03442c432#%E7%AD%89%E5%80%A4%E6%AF%94%E8%BC%83%E3%81%8C%E7%99%BA%E7%94%9F%E3%81%99%E3%82%8B%E5%A0%B4%E9%9D%A2) - [deep-equal - npm]
(https://www.npmjs.com/package/deep-equal)