4

I have a list in variable like:

var name_list = some_list

console.log(name_list)

Array[3]
   0: Object
       name: "Johny"
   1: Object
       name: "Monty"
   2: Object3:
      name: "Johny"

I want to get the list with non repetitive list. How can I do this ?

Update

I tried with this..

var unique_name = [ ...new Set(name_list.map(name => {
                return name.name
            }))]

It works fine but I want the object that are filtered unique according to name.

Any idea ??

7
  • use es6 feature set [ ...new Set(array) ] Commented May 4, 2016 at 7:54
  • @diEcho or anyone else, any ideas why [ ...new Set(array) ] doesn't work? Commented May 4, 2016 at 8:03
  • will it gives uniquey according to name.. what if there are other values too like age, sex but I want accorgint to name Commented May 4, 2016 at 8:07
  • Do you want a deduped list of names, or an array with the duplicate objects removed? Commented May 4, 2016 at 8:19
  • arry with duplicate object removed... that duplication should be name.. Commented May 4, 2016 at 8:24

6 Answers 6

4

Another approach I don't see in here would be to use a Map

var name_list = [{name: "Johny"}, {name: "Monty"}, {name: "Johny"}];

// Make a mapping of name to object, then pullout objects.
var name_map = new Map(name_list.map(o => [o.name, o]));
var unique_names = [...name_map.values()];

Note, this will take the last object for each name instead of the first, but you could always do name_list.slice().reverse().map( instead of you need specifically the first object found.

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

1 Comment

The best of the lot IMO!
4

reduce over the array keeping a lookup of previous entries to check against.

const arr=[{name:"Johny"},{name:"Monty"},{name:"Johny"}];

function dedupeByKey(arr, key) {
  const tmp = {};
  return arr.reduce((p, c) => {
    const k = c[key];
    if (tmp[k]) return p;
    tmp[k] = true;
    return p.concat(c);
  }, []);
}

console.log(dedupeByKey(arr, 'name'));

Or you can filter using a similar approach:

const arr=[{name:"Johny"},{name:"Monty"},{name:"Johny"}];

function dedupeByKey(arr, key) {
  const temp = arr.map(el => el[key]);
  return arr.filter((el, i) =>
    temp.indexOf(el[key]) === i
  );
}

console.log(dedupeByKey(arr, 'name'));

1 Comment

I like your second approach
2

Filter to keep only those elements which are the first occurrence of the name (in other words, whose index is the same as the index of the first occurrence):

var name_list = [{name: "Johny"}, {name: "Monty"}, {name: "Johny"}];

var filtered = name_list . filter(
  (elt, i, a) => i === a.findIndex(
    elt2 => elt.name === elt2.name
  )
);

document.getElementById('result').textContent = JSON.stringify(filtered);
<pre id='result'></pre>

This might not be the fastest approach, but it could be the simplest.

1 Comment

A+ for keeping it simple
1

You can use this little distinctByProp( theArray, propertyName) function.

I hope it helps

distinctByProp = (theArray, prop) => {
    let tempArray = [];
    let isFound = obj => tempArray.find( n => n[prop] === obj[prop]);
    theArray.forEach( current => !isFound(current) && tempArray.push(current));
    return tempArray;
}

Usage is like:

let names_list = [{name: "Johny"}, {name: "Johnyh"}, {name: "Max"}, {name: "Monty"}, {name: "Johnyh"}, {name: "Max"}];

let distinct = distinctByProp(names_list, "name");

console.log(distinct);

I hope it helps

Comments

0

You could use Array#filter().

var name_list = [{ name: "Johny" }, { name: "Monty" }, { name: "Johny" }],
    filtered = name_list.filter(a => {
        this.my = this.my || Object.create(null);
        if (!this.my[a.name]) {
            this.my[a.name] = true;
            return true;
        }
    });

document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');

3 Comments

If you know how arrow functions work then you know that passing Object.create(null) is pointless and your code might fail.
can use ({}) instead of Object.create(null)
@diEcho, no, you get otherwise all prototypes of Object.
0

This is my resumed form of this type of unique. Not only for one field but for all the root fields of the object.

const unique = l => l.filter(
  (e1, i, a) => i === a.findIndex(
    e2 => Object.keys(e1)
      .map(x => e1[x] === e2[x])
      .reduce((x,y) => x && y)
  )
)

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.