我会使用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来玩它。