'javascript and es6 filter array with unique key

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 ??



Solution 1:[1]

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.

Solution 2:[2]

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'));

Solution 3:[3]

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.

Solution 4:[4]

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

Solution 5:[5]

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>');

Solution 6:[6]

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)
  )
)

Solution 7:[7]

There is an issue on github similar to your problem

Answer: Likely you missed the as_asgi() in your routing.py

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 loganfsmyth
Solution 2
Solution 3
Solution 4 Maxali
Solution 5
Solution 6 mAlaniz
Solution 7