FIltering out entries with a property using Lodash

In my React application i have a function, that merges two arrays where I'm currently using the lodash library with the unionBy function

Here is my code so far:

export function generateDisplayedLabels(systemLabels, masterState){
  const mappedSystemlabels = systemLabels.map(label => Object.assign(label, {type: "system"}))
  const mappedMasterState = masterState.map(label => Object.assign(label, {type: "master"}))
  const displayedLabels = _.unionBy(mappedSystemlabels, mappedMasterState, 'geometry');
  return displayedLabels
}

Basically i mark the two seperate arrays, then try to filter them on their geometry object.

But in the end result, i see entries having duplicate entries (i think this might be due to the fact, that it does not "unionBy" complex objects as easily.

Here is an example.

[{ data: {...},
   geometry: {height: 1.24703087885986
type: "RECTANGLE"
width: 60.25210084033614
x: 30.952380952380953
y: 87.50989707046713
}, 
type: "master" },
data: {...},
   geometry: {height: 1.24703087885986
type: "RECTANGLE"
width: 60.25210084033614
x: 30.952380952380953
y: 87.50989707046713
}, 
type: "" }

This results in both entries still being in the new array.

Ideally i would like to filter out based on the geometry object, and if both exist, it should prioritize the one with {type: master}

Can someone help me implement this logic into the existing function?

Upvotes: 1

Views: 89

Answers (1)

Ravi Kukreja
Ravi Kukreja

Reputation: 647

Using reduce:

Note: For the comparison JSON.stringify(item.geometry) === JSON.stringify(cur.geometry) to work the properties in geometry must be in the same order.

let mappedMasterState = [{ 
  geometry: {
      height: 1.24703087885986,
      type: "RECTANGLE",
      width: 60.25210084033614,
      x: 30.952380952380953,
      y: 87.50989707046713,
  }, 
  type: "master" }
];
let mappedSystemlabels = [{
  geometry: {
    height: 1.24703087885986,
    type: "RECTANGLE",
    width: 60.25210084033614,
    x: 30.952380952380953,
    y: 87.50989707046713,
  }, 
  type: "" }
];



let displayedLabels = [...mappedMasterState, ...mappedSystemlabels];

displayedLabels = displayedLabels.reduce((acc, cur) => {  
  const isExists = acc.find( (item, index) => JSON.stringify(item.geometry) === JSON.stringify(cur.geometry));
  if(isExists && isExists.type === "master") return acc;    
  
  else if (isExists) acc.splice(acc.indexOf(isExists), 1);              
  acc.push(cur);
  return acc;
}, [])

console.log(displayedLabels)

Upvotes: 1

Related Questions