Filter only unique values from an array of object javascript

Viewed 940

I have an array of objects i want to filter only the unique style and is not repeated .

const arrayOfObj = [ {name:'a' , style:'p'} , {name:'b' , style:'q'} , {name:'c' , style:'q'}]

result expected : [ {name:'a' , style:'p'}]

6 Answers

On of the possible solutions depending on your performance / readability needs can be:

arrayOfObj.filter(a => arrayOfObj.filter(obj => obj.style === a.style).length === 1)

Here is a solution in O(n) time complexity. You can iterate all entries to track how often an entry occurs. And then use the filter() function to filter the ones that occur only once.

const arrayOfObj = [
  { name: "a", style: "p" },
  { name: "b", style: "q" },
  { name: "c", style: "q" },
]

const styleCount = {}

arrayOfObj.forEach((obj) => {
  styleCount[obj.style] = (styleCount[obj.style] || 0) + 1
})

const res = arrayOfObj.filter((obj) => styleCount[obj.style] === 1)

console.log(res)

Use splice when you find the existing item and remove it

const arrayOfObj = [{
  name: 'a',
  style: 'p'
}, {
  name: 'b',
  style: 'q'
}, {
  name: 'c',
  style: 'q'
}]

const result = arrayOfObj.reduce((acc, x) => {
  const index = acc.findIndex(y => y.style === x.style);
  if (index >= 0) {
    acc.splice(index, 1);
  } else {
    acc.push(x);
  }
  return acc;

}, [])

console.log(result)

You reduce it. Check if in the array already an element with the same style exists and remove it from the accumulator otherwise push it to the accumulator

const arr = [
  { name: "a", style: "p" },
  { name: "b", style: "q" },
  { name: "c", style: "q" }
];

  let result = arr.reduce((a,v) => {
     let i = a.findIndex(el => el.style === v.style);
     if(i !== -1) {
        a.splice(i,1);
        return a;
     }
     a.push(v)
     return a;
  },[])

console.log(result);

Here is a solution in O(n) time complexity. You can iterate all entries to track how often an entry occurs. And then use the filter() function to filter the ones that occur only once.

const arrayOfObj = [ {name:'a' , style:'p'} , {name:'b' , style:'q'} , {name:'c' , style:'q'}];

let count = {};

arrayOfObj.forEach(({style}) => {
    count[style] = (count[style] || 0) + 1;
});

let result = arrayOfObj.filter(({style}) => count[style] === 1);
console.log(result);

There is a one liner answer too if you are using lodash library (uniqBy(array, iteratee))

const arr = [
  { name: "a", style: "p" },
  { name: "b", style: "q" },
  { name: "c", style: "q" }
];
let result = _.uniqBy(arrayOfObj,'style')
console.log(result)
Related