Reputation: 3327
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
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