Remove duplicates in an object array Javascript

前端 未结 8 1082
误落风尘
误落风尘 2020-12-01 16:03

I have an array of objects

list = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}, {x:1,y:2}]

And I\'m looking for an efficient way (if possible O(

相关标签:
8条回答
  • 2020-12-01 16:40

    Vanilla JS version:

    const list = [{x:1,y:2}, {x:3,y:4}, {x:5,y:6}, {x:1,y:2}];
    
    function dedupe(arr) {
      return arr.reduce(function(p, c) {
    
        // create an identifying id from the object values
        var id = [c.x, c.y].join('|');
    
        // if the id is not found in the temp array
        // add the object to the output array
        // and add the key to the temp array
        if (p.temp.indexOf(id) === -1) {
          p.out.push(c);
          p.temp.push(id);
        }
        return p;
    
        // return the deduped array
      }, {
        temp: [],
        out: []
      }).out;
    }
    
    console.log(dedupe(list));

    0 讨论(0)
  • 2020-12-01 16:42

    I would use a combination of Arrayr.prototype.reduce and Arrayr.prototype.some methods with spread operator.

    1. Explicit solution. Based on complete knowledge of the array object contains.

    list = list.reduce((r, i) => 
      !r.some(j => i.x === j.x && i.y === j.y) ? [...r, i] : r
    , [])
    

    Here we have strict limitation on compared objects structure: {x: N, y: M}. And [{x:1, y:2}, {x:1, y:2, z:3}] will be filtered to [{x:1, y:2}].

    2. Generic solution, JSON.stringify(). The compared objects could have any number of any properties.

    list = list.reduce((r, i) => 
      !r.some(j => JSON.stringify(i) === JSON.stringify(j)) ? [...r, i] : r
    , [])
    

    This approach has a limitation on properties order, so [{x:1, y:2}, {y:2, x:1}] won't be filtered.

    3. Generic solution, Object.keys(). The order doesn't matter.

    list = list.reduce((r, i) => 
      !r.some(j => !Object.keys(i).some(k => i[k] !== j[k])) ? [...r, i] : r
    , [])
    

    This approach has another limitation: compared objects must have the same list of keys. So [{x:1, y:2}, {x:1}] would be filtered despite the obvious difference.

    4. Generic solution, 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
    , [])
    

    With the last approach objects are being compared by the number of keys, by keys itself and by key values.

    I created a Plunker to play with it.

    0 讨论(0)
提交回复
热议问题