-1

I'm trying to remove all instances of duplicate objects in a javascript array. The helper function below works well for removing duplicates and keeping 1 instance, but I want to basically disqualify any object that has an equal property to another object by removing all instances.

function removeDuplicates(data, key) {
    return [
        ... new Map(
            data.map(x => [key(x), x])
        ).values()
    ]
}

Example of uncleaned array:

[
  {
    name: 'name1',
    value: 15
  },
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  },
  {
    name: 'name1',
    value: 18
  }
]

Returned from above helper function:

[
  {
    name: 'name1',
    value: 15
  },
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  }
]

What I'd like to be returned:

[
  {
    name: 'name2',
    value: 16
  },
  {
    name: 'name3',
    value: 17
  }
]

Would appreciate any ideas!

1
  • 2
    What if two values are the same? Is it just the name key? Can you use the code here but invert the condition and change id to name to match your key, i.e. values.filter(e => !lookup[e.name])? Commented Sep 5, 2021 at 20:39

2 Answers 2

0

Assuming your intention was to call the function above in this manner: removeDuplicates(data, (x) => x.name), here is my implementation

function removeDuplicates(data, key) {
    return data.filter((o, idx) => {
        const remainingData = [...data.slice(0, idx), ...data.slice(idx + 1)];
        return !remainingData.some(o2 => key(o) === key(o2));
    });
}

Basically, for each element in the data array, I check for the remaining values, if there is another element with the same "key". I use the "some" method for Javascript arrays to test this. Only values that don't pass this test are returned by the filter function.


As some have noted - this is not the most efficient solution, so let me provide a better implementation:

function removeDuplicatesBetter(data, key) {
    return data.filter((o, idx) => {
        return !data.some((o2, idx2) => idx !== idx2 && key(o) === key(o2));
    });
}

Here is a Repl.it demonstrating the solutions: https://replit.com/@VehpuS/removeDuplicates

Sign up to request clarification or add additional context in comments.

3 Comments

This was a very complex approach to this problem since you are filtering it twice anyways and also creating a list of objects in every iteration. (i did not vote ur anwer down)
While I agree, at least for the size of input provided, performance is less of an issue :). But fair enough - I'll add a more efficient implementation
The second solution works great, thanks!
0

function removeDuplicates(arr, key) {
    const duplicates = arr.reduce((seen, obj) => ((seen[obj[key]] = seen.hasOwnProperty(obj[key])), seen), {});
    return arr.filter((obj) => !duplicates[obj[key]]);
}

//Usage: 
const input = [
    {
        name: "name1",
        value: 15,
    },
    {
        name: "name2",
        value: 16,
    },
    {
        name: "name3",
        value: 17,
    },
    {
        name: "name1",
        value: 18,
    },
];

const output = removeDuplicates(input, "name");

console.log(output);
//output: [ { name: 'name2', value: 16 }, { name: 'name3', value: 17 } ]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.