Sort array by unique id, by keeping last in Javascript - Stack Overflow

I'm trying to make unique id list from an array that has multiple same id's. But I want it to

I'm trying to make unique id list from an array that has multiple same id's. But I want it to keep the last one, not the first one. The code I have here keeps first unique object. Is there an Array.findLastIndex() I can use here. I searched but couldn't find a similar question.

[{id:2,name:'first'}, {id:2,name:'second'}, {id:3}]
    .filter((v, i, a) => a.findIndex((t) => (t.id === v.id)) === i)

That code returns :

[{id: 2, name: "first"}, {id: 3}]

But I want:

[{id: 2, name: "second"}, {id: 3}]

I have wrote the next one which gives me the result, but ideally I do not want to copy and reverse my array twice, it will be quite inefficient for long arrays.

[{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()

I'm trying to make unique id list from an array that has multiple same id's. But I want it to keep the last one, not the first one. The code I have here keeps first unique object. Is there an Array.findLastIndex() I can use here. I searched but couldn't find a similar question.

[{id:2,name:'first'}, {id:2,name:'second'}, {id:3}]
    .filter((v, i, a) => a.findIndex((t) => (t.id === v.id)) === i)

That code returns :

[{id: 2, name: "first"}, {id: 3}]

But I want:

[{id: 2, name: "second"}, {id: 3}]

I have wrote the next one which gives me the result, but ideally I do not want to copy and reverse my array twice, it will be quite inefficient for long arrays.

[{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()
Share Improve this question edited Jun 27, 2019 at 20:45 Shidersz 17.2k2 gold badges27 silver badges51 bronze badges asked Jun 27, 2019 at 18:11 chickenschickens 22.4k7 gold badges61 silver badges57 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6

You can store them in a Map id => object, and pull the values back out:

arr = [{id:2,name:'first'},{id:2,name:'second'},{id:3}]

result = [...new Map(arr.map(x => [x.id, x])).values()]

console.log(result)

Since the Map constructor overwrites existing values, you automagically get the last one.

As noted in the ments, after this, the result elements will be ordered by the first occurrence, not by the last:

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)

If you additionally want to sort by id, as your title suggests, then add

.sort((a, b) => a.id - b.id)

to the above.

One solution is to use Array.reduce() to generate an object using the id property as the keys while overwriting previous values. Then you can use Object.values() on the generated object:

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);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

You could reverse the array and take the first found uniqe value. After filtering reverse the result set.

var array = [{ id: 2, name: 'first' }, { id: 2, name: 'second' }, { id: 3 }],
    unique = array
        .reverse()
        .filter((s => ({ id }) => !s.has(id) && s.add(id))(new Set))
        .reverse();

console.log(unique);

A classic approach.

var array = [{ id: 2, name: 'first' }, { id: 2, name: 'second' }, { id: 3 }],
    seen = Object.create(null),
    unique = array.reduceRight((r, o) => {
        if (!seen[o.id]) {
            r.unshift(o);
            seen[o.id] = true;
        }
        return r;
    }, []);

console.log(unique);

I like Shidersz answer the most, but here's another possibility:

    let arr = [
      {id:2, name:'first'},
      {id:2, name:'second'},
      {id:3}
    ];

    let res = arr.filter((v, i) => {
      for (let j = i + 1; j < arr.length; j++) {
        if (v.id === arr[j].id) return false
      }
      return true;
    })
    console.log(res);

My guess is that it uses less memory (doesn't have to create an intermediate object) but it probably runs slower due to not using constant time to look for duplicates. Not by much though, since the lookup is quite scope between current value and next first duplicate.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744845079a4596785.html

相关推荐

  • Sort array by unique id, by keeping last in Javascript - Stack Overflow

    I'm trying to make unique id list from an array that has multiple same id's. But I want it to

    2天前
    70

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信