0

I am trying to take an array of objects and do 2 things.

1.) Remove objects from the array that are duplicated, create a new array with the names of the items that were duplicates.

Original:

var duplicates = [];

var objects = [
    {
        name: 'foo',
        nums: [1,2]
    },
    {
        name: 'bar',
        nums: [3,2]
    },
    {
        name: 'baz',
        nums: [1,2]
    },
    {
        name: 'bum',
        nums: [2,3]
    },
    {
        name: 'bam',
        nums: [1,2]
    },
]

Desired Output:

duplicates = ['foo', 'baz', 'bam'];

objects = [
    {
        name: 'bar',
        nums: [3,2]
    },
    {
        name: 'bum',
        nums: [2,3]
    }
]

Can anyone help with this? I am using lodash in my project.

6
  • What if you have duplicates of both [1,2] and [3,4]? They all go into duplicates? Commented Jan 9, 2015 at 1:22
  • When you say 'duplicate', do you mean the arrays are the same object, or that the arrays have the same length and order of items, or have the same length but not order of items? Commented Jan 9, 2015 at 1:24
  • Isn't this the same question? stackoverflow.com/questions/27852356/… Commented Jan 9, 2015 at 1:24
  • @Barmar In my particular problem, there will never be multiple duplicates. I am dealing with a array of 3 sub arrays and while it's possible that all 3 match, in most cases, only 2 of them will match Commented Jan 9, 2015 at 16:43
  • @Xotic750 It's similar but it's actually the entire solution, and the other was a component of a certain way I was trying to solve my problem. Thought it beneficial to leave both. To answer your question, the order will always be the same so there would never be a [1,2] and a [2,1] and if so I would not want them to be counted as duplicates. Commented Jan 9, 2015 at 16:44

2 Answers 2

1

If order of elements in nums array matters:

_.pluck(_.flatten(_.filter(_.groupBy(objects, "nums"), function(el) {
   return (el.length !== 1)
})), "name")

or a bit tidier

var hmap = _(objects).groupBy("nums").values();
var unique = hmap.where({'length': 1}).flatten().value();
var duplicates = hmap.flatten().difference(unique).value();
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks and this is very close. However, Your solution assumes I know the value of "1" in the duplicates. In my real-world scenario, I will not know any of the values to filter by.
0

I don't know underscore.js, here's how to do it with plain JS:

var counts = {};
var duplicates = [];
for (var i = 0; i < objects.length; i++) {
    var str = JSON.stringify(objects[i].nums);
    if (str in counts) {
        counts[str]++;
    } else {
        counts[str] = 1;
    }
}
objects = objects.filter(function(val) {
  if (counts[JSON.stringify(val.nums)] == 1) {
    return true;
  } else {
    duplicates.push(val.name);
    return false;
  }
});

DEMO

2 Comments

Thanks for the response, but it does not seem to work jsbin.com/bekuku/1/edit?js,console
I fixed the problems. I was only saving one of the names in the duplicate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.