69. `_.isEqual()`を実装する
シェアしよう
少し工夫が必要 - accepted / - tried
_.isEqualを使えば、複雑なデータ型を比較することが容易にできる。
isEqual
を実装するのはいかがですか?
lodash の実装ではたくさんのデータ型をサポートしているけど、ここでは以下のデータ型だけサポートすれば良い
- primitives
- plain objects (object literals)
- array
Objectを比較するときに、列挙可能な属性だけ見ると良い、prototypeは考慮不要。
const a = {a: 'bfe'}
const b = {a: 'bfe'}
isEqual(a, b) // true
a === b // false
const c = [1, a, '4']
const d = [1, b, '4']
isEqual(c, d) // true
c === d // false
Lodashの実装では変な挙動がある (github issue)、例えば以下のコード:
const a = {}
a.self = a
const b = {self: a}
const c = {}
c.self = c
const d = {self: {self: a}}
const e = {self: {self: b}}
lodash.isEqual
では以下の結果を返してくる。falseがあったことに留意してください。
// result from lodash implementation
_.isEqual(a, b) // true
_.isEqual(a, c) // true
_.isEqual(a, d) // true
_.isEqual(a, e) // true
_.isEqual(b, c) // true
_.isEqual(b, d) // true
_.isEqual(b, e) // false
_.isEqual(c, d) // true
_.isEqual(c, e) // true
_.isEqual(d, e) // true
lodashで考慮されたパフォーマンスの懸念を置いといて、この問題では上記の変な共同を避けるべき、つまり上記の例では全部true を返して、さらにmaximum call stack size exceededエラーはならない。