1

I have a list of objects:

   [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]

I need a simple way to filter out duplicates with regard to the name property, so:

 [{name: "bob", age: "14"}, {name: "sue", age: "21"}]

There seem to be quite a few array duplicate removal questions, but not any based on a property. It can ignore all other fields.

4
  • 4
    Does it matter which 'bob' is removed? Should it always be the first, or the youngest? Commented May 20, 2016 at 16:51
  • Doesnt matter, any order Commented May 20, 2016 at 16:52
  • 5
    possible duplicate of stackoverflow.com/questions/2218999/… Commented May 20, 2016 at 16:52
  • Look into .reduce() Commented May 20, 2016 at 16:54

5 Answers 5

1

Iterate the array, place all name values in a hash and skip objects whose name is already in the hash:

filterBy = function(ary, prop) {
  var seen = {};
  return ary.filter(function(item) {
    var key = item[prop];
    if(seen[key] === 1)
      return false;
    seen[key] = 1;
    return true;
  });
}

// 
a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]

b = filterBy(a, 'name');

console.log(b);

ES6 version:

filterBy = function(ary, prop) {
  var seen = new Set();
  return ary.filter(item => !seen.has(item[prop]) && seen.add(item[prop]));
}

a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]

b = filterBy(a, 'name');

console.log(b);

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

Comments

0

You can do it with 2 for loops as follows. All you have to do is, keeping a result array and every time you insert into it, check whether the name attributes are equal.

function findDuplicate(){
  var array= [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];

  var result=[];
  for(x in array){
    var found=false;
    for(y in result){
      if(result[y].name.localeCompare(array[x].name)==0){
        found=true;
      }
    }
    if(!found){
      result.push(array[x]);
    }
  }
  console.log(result);
}

Comments

0

You could do this with forEach and thisArg param.

var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];
var result = [];

data.forEach(function(e) {
  if (!this[e.name]) {
    this[e.name] = e;
    result.push(this[e.name]);
  }
}, {});

console.log(result)

Or with forEach and map()

var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}], result =[];

data.forEach(function(e) {
  if(result.map(a => {return a.name}).indexOf(e.name) == -1 ) result.push(e);
});

console.log(result)

Comments

0

You could use Array#filter and a this object for marking, if the same name is already filtered.

var array = [{ name: "bob", age: "14" }, { name: "bob", age: "16" }, { name: "sue", age: "21" }],
    filtered = array.filter(function (a) {
        if (!this[a.name]) {
            this[a.name] = true;
            return true;
        }
    }, Object.create(null));

console.log(filtered);

Comments

0

For the straightforward comparison in the Q., there are some good answers here. If you want to provide a custom comparison function that will work on e.g. object values, or that uses a RegExp, then take a look at the following.

var dedupwhen = function(fn, list){
    if(list[0] === undefined){
        return [];
    }
    // Join the first item to the remainder that has had the first
    // item filtered out (according to fn) and then been
    // deduplicated itself.
    return [list[0]].concat(dedupwhen(fn, list.slice(1).filter(function(item){
        return !fn(list[0], item);
    })));
};

var similarname = function(x,y){
    return RegExp('^' + x.name + '$', 'i').test(y.name);
};

var list = [
    {name: 'Sue', age: 44},
    {name: 'Bob', age: "14"},
    {name: 'bob', age: "16"},
    {name: 'sue', age: "21"}
];
console.log(dedupwhen(similarname, list));

Comments

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.