Removing duplicates with in an object array using angular 4

Viewed 24976

I have an array with below list of items as shown in image , I would like to remove the duplicates
[L7-LO, %L7-LO] from that array.

Array with repetitions
I have tried with the following conditions:

Scenario 1 :

this.formulalist.filter((el, i, a) => i == a.indexOf(el))

Scenario 2:

Observable.merge(this.formulalist).distinct((x) => x.Value)
          .subscribe(y => {
       this.formulalist.push(y)
   });

Scenario 3:

this.formulalist.forEach((item, index) => {
        if (index !== this.formulalist.findIndex(i => i.Value == item.Value)) 
        {
            this.formulalist.splice(index, 1);
        }

    });

None of the three scenarios above were able to remove the duplicates from that array. Could any one please help on this query?

7 Answers

angular is not necessary use vanillajs filter the elements with only one occurrence and add to the new list the first occurrence

let newFormulalist =  formulalist.filter((v,i) => formulalist.findIndex(item => item.value == v.value) === i);

Try populating a new array without duplicates. Assign the new array later to formulalist.

newArr = []
this.formulalist.forEach((item, index) => {
    if (this.newArr.findIndex(i => i.Value == item.Value) === -1) 
    {
        this.newArr.push(item)
    }

});
this.formulalist = this.newArr

EDIT

Looking at the answer above, the solution seems so outdated. A better approach would have been to use an Array.filter() than a Array.forEach().

But, having a better solution would be nice, now when I see this question, I feel findIndex() not to be a good approach because of the extra traversal.

I may have a Set and store the values in the Set on which I want to filter, If the Set has those entries, I would skip those elements from the array.

Or a nicer approach is the one that is used by Akitha_MJ, very concise. One loop for the array length, an Object(Map) in the loop with keys being the value on which we want to remove duplicates and the values being the full Object(Array element) itself. On the repetition of the element in the loop, the element would be simply replaced in the Map. Later just take out the values from the Map.

const result = Array.from(this.item.reduce((m, t) => m.set(t.name, t), new Map()).values());

Hope this works !!

// user reduce method to remove duplicates from object array , very easily

  this.formulalist= this.formulalist.reduce((a, b) => {
      if (!a.find(data => data.name === b.name)) {
        a.push(b);
      }
      return a;
    }, []);

// o/p = in formulalist you will find only unique values

Use a reducer returning a new array of the unique objects:

const input = [{
    value: 'L7-LO',
    name: 'L7-LO'
  },
  {
    value: '%L7-LO',
    name: '%L7-LO'
  },
  {
    value: 'L7-LO',
    name: 'L7-LO'
  },
  {
    value: '%L7-LO',
    name: '%L7-LO'
  },
  {
    value: 'L7-L3',
    name: 'L7-L3'
  },
  {
    value: '%L7-L3',
    name: '%L7-L3'
  },
  {
    value: 'LO-L3',
    name: 'LO-L3'
  },
  {
    value: '%LO-L3',
    name: '%LO-L3'
  }
];
console.log(input.reduce((acc, val) => {
  if (!acc.find(el => el.value === val.value)) {
    acc.push(val);
  }
  return acc;
}, []));

Filtering for unique values is much faster with assigning values to some object properties - there not will be duplicates. This approach gets better and better with every +1 member of initial array, because looping will be causing fast algorithm complications

let arr = [
  {value: 'L7-LO', name: 'L7-LO'},
  {value: '%L7-LO', name: '%L7-LO'},
  {value: 'L7-LO', name: 'L7-LO'},
  {value: '%L7-LO', name: '%L7-LO'},
  {value: 'L7-L3', name: 'L7-L3'},
  {value: '%L7-L3', name: '%L7-L3'},
  {value: 'LO-L3', name: 'LO-L3'},
  {value: '%LO-L3', name: '%LO-L3'}
];
let obj = {};

const unique = () => {
  let result = [];
  
  arr.forEach((item, i) => {
    obj[item['value']] = i;
  });
  
  for (let key in obj) {
    let index = obj[key];
    result.push(arr[index])
  }
  
  return result;
}

arr = unique(); // for example; 

console.log(arr);

if you are working using ES6 and up, basic JS using map and filter functions makes it easy.

var array = [{value:"a"},{value:"b"},{value:"c"},{value:"a"},{value:"c"},{value:"d"}];

console.log(array.filter((obj, pos, arr) => {
    return arr.map(mapObj => mapObj["value"]).indexOf(obj["value"]) === pos;
}));

Related