I have two objects with same length and a common property edge_id on each Id. I would like to add to the second object to the properties of the first object.
I have a MapLibre map that I would like to add some properties coming from an API (the second object).
First object
[
{
"type": "Feature",
"properties": {
"edge_id": 67135,
"color": "#f7fabf"
},
"geometry": {
"type": "Polygon",
"coordinates": [ ]
}
},
{
"type": "Feature",
"properties": {
"edge_id": 15984,
"color": "#fcd6a4"
},
"geometry": {
"type": "Polygon",
"coordinates": [ ]
}
},
]
Second object
[
{
"edge_id": 67135,
"name": "R12",
"length": 0.14907826598895346,
"speed": null,
"lanes": null
},
{
"edge_id": 15984,
"name": "Pont de Sully",
"length": 0.01577450403315043,
"speed": 30,
"lanes": 2
},
]
I want the below output for edge_id : 67135:
{
"type": "Feature",
"properties": {
"edge_id": 67135,
"color": "#f7fabf",
"name": "R12",
"length": 0.14907826598895346,
"speed": null,
"lanes": null
},
"geometry": {
"type": "Polygon",
"coordinates": [ ]
}
},
I would first collect the second object's items by edge_id so that we can look them up in constant time later on:
const secondObjectByEdgeId = secondObject.reduce(
(o, x) => ({ ...o, [x.edge_id]: x }),
{}
);
And then iterate over the first object's items, enhancing their properties field with what we just collected above:
const merged = firstObject.map((x) => ({
...x,
properties: {
...x.properties,
...secondObjectByEdgeId[x.properties.edge_id]
}
}));
Note that the above approach will simply ignore any item in the second object whose edge_id is not present in the first object.
Same algorithm relying on side-effects:
const secondObjectByEdgeId = secondObject.reduce(
(o, x) => {
o[x.edge_id] = x;
return o;
},
{}
);
firstObject.forEach((x) => {
Object.assign(x.properties, secondObjectByEdgeId[x.properties.edge_id]);
});
firstObject has now been updated directly.