我会将Arrayr.prototype.reduce 和Arrayr.prototype.some 方法与展开运算符结合使用。
1.显式解决方案。基于数组对象包含的完整知识。
list = list.reduce((r, i) =>
!r.some(j => i.x === j.x && i.y === j.y) ? [...r, i] : r
, [])
这里我们对比较对象结构有严格的限制:{x: N, y: M}。而[{x:1, y:2}, {x:1, y:2, z:3}] 将被过滤为[{x:1, y:2}]。
2。通用解决方案,JSON.stringify()。被比较的对象可以有任意数量的任意属性。
list = list.reduce((r, i) =>
!r.some(j => JSON.stringify(i) === JSON.stringify(j)) ? [...r, i] : r
, [])
这种方法对属性顺序有限制,所以[{x:1, y:2}, {y:2, x:1}]不会被过滤。
3。通用解决方案,Object.keys()。顺序无关紧要。
list = list.reduce((r, i) =>
!r.some(j => !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
此方法还有另一个限制:比较对象必须具有相同的键列表。
因此,[{x:1, y:2}, {x:1}] 将被过滤,尽管存在明显差异。
4.通用解决方案,Object.keys() + .length。
list = list.reduce((r, i) =>
!r.some(j => Object.keys(i).length === Object.keys(j).length
&& !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
, [])
最后一种方法是通过键的数量、键本身和键值来比较对象。
我创建了一个Plunker 来玩它。