我正在尝试id从具有多个相同ID的数组中制作唯一列表。但是我希望它保留最后一个,而不是第一个。我在这里的代码保留了第一个唯一对象。Array.findLastIndex()我可以在这里使用吗?我搜索了但找不到类似的问题。
[{id:2,name:'first'}, {id:2,name:'second'}, {id:3}]
.filter((v, i, a) => a.findIndex((t) => (t.id === v.id)) === i)
Run Code Online (Sandbox Code Playgroud)
该代码返回:
[{id: 2, name: "first"}, {id: 3}]
Run Code Online (Sandbox Code Playgroud)
但我想要:
[{id: 2, name: "second"}, {id: 3}]
Run Code Online (Sandbox Code Playgroud)
我写了下一个给我结果的代码,但是理想情况下,我不想复制和反转我的数组两次,这对于长数组来说效率很低。
[{id:2,name:'first'}, {id:2,name:'second'}, {id:3}]
.slice().reverse()
.filter((v, i, a) => a.findIndex((t) => (t.id === v.id)) === i)
.reverse()
Run Code Online (Sandbox Code Playgroud)
您可以将它们存储在Mapid =>对象中,然后将值拉回:
arr = [{id:2,name:'first'},{id:2,name:'second'},{id:3}]
result = [...new Map(arr.map(x => [x.id, x])).values()]
console.log(result)Run Code Online (Sandbox Code Playgroud)
由于Map构造函数会覆盖现有值,因此您可以自动获得最后一个值。
如评论中所述,此后,结果元素将按第一次出现而不是最后一次进行排序:
arr = [
{id:3,name:'first 3'},
{id:2,name:'first 2'},
{id:2,name:'second 2'},
{id:3,name:'second 3'}]
result = [...new Map(arr.map(x => [x.id, x])).values()]
console.log(result)Run Code Online (Sandbox Code Playgroud)
如果您还想按ID 排序(如标题所示),请添加
.sort((a, b) => a.id - b.id)
Run Code Online (Sandbox Code Playgroud)
以上。
一种解决方案是使用Array.reduce()id在覆盖先前值的同时使用属性作为键来生成对象。然后可以在生成的对象上使用Object.values():
let arr = [
{id:2, name:'first'},
{id:2, name:'second'},
{id:3}
];
let res = Object.values(arr.reduce((acc, obj) => (acc[obj.id] = obj, acc), {}));
console.log(res);Run Code Online (Sandbox Code Playgroud)
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}Run Code Online (Sandbox Code Playgroud)