Reputation: 371
I have two arrays of objects that I need to merge together to only get one array of object. There is a lot of objects, both have more than 500+ objects
This is an exemple of the structure of the two array of objects :
let API = [
{
actif: true,
id: 8,
creation_user: "David",
date_creation: "févr 4 2022 12:17PM",
description: "A description",
version: "v1r1"
},
{
actif: true,
id: 10,
creation_user: "Julien",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
},
{
actif: false,
id: 20,
creation_user: "Tom",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
}
]
let Parameters = [
{
id: 10,
name: "codeRR",
type: "string"
},
{
id: 20,
name: "codeAA",
type: "string"
},
{
id: 20,
name: "codeCC",
type: "string"
}
]
As we can see, they both have an ID, this ID is the same in both arrays. But not everytime, API can have no parameter.
What i'm trying to achieve is to get in the second array, the "name" and "type", and to add it to the first array (or in a new array).
I've tried with .map on the first array (also tried with the second one) :
let Ressource = api.map(item => Object.assign({}, item, parametre.find(target => target.id === item.id)));
// Result of Ressource
[
{
actif: true,
id: 8,
creation_user: "David",
date_creation: "févr 4 2022 12:17PM",
description: "A description",
version: "v1r1";
name: "codeRR",
type: "string
}
]
// Want I want :
[
{
actif: true,
id: 8,
creation_user: "David",
date_creation: "févr 4 2022 12:17PM",
description: "A description",
version: "v1r1",
parameter: [
{
name: "codeRR",
type: "string
},
{
name: "codePP",
type: "string
}
]
}
]
But when an API have multiple parameter it overwrite the previous one. Is it possible to make something like this in my API
parameter: [{"name": "codeRR", type: "string"}, {"name": "codePP", "type": "string"}]
Upvotes: 0
Views: 613
Reputation: 8168
Group the Parameters
array by their id
using Array.prototype.reduce, this would give an object where the keys are the id
s and the values are an array of parameter objects.
Loop over the API
array and using the object created above add the parameter
property wherever the parameter information is available.
let
API = [
{ actif: true, id: 8, creation_user: "David", date_creation: "févr 4 2022 12:17PM", description: "A description", version: "v1r1" },
{ actif: true, id: 10, creation_user: "Julien", date_creation: "févr 10 2022 12:17PM", description: "A description", version: "v1r2" },
{ actif: false, id: 20, creation_user: "Tom", date_creation: "févr 10 2022 12:17PM", description: "A description", version: "v1r2" },
],
Parameters = [
{ id: 10, name: "codeRR", type: "string" },
{ id: 20, name: "codeAA", type: "string" },
{ id: 20, name: "codeCC", type: "string" },
],
ParametersGroup = Parameters.reduce((r, p) => ((r[p.id] ??= []).push(p), r), {}),
APIWithParams = API.map((o) => ({
...o,
...(ParametersGroup[o.id] && { parameters: ParametersGroup[o.id] }),
}));
console.log(APIWithParams);
If you want to handle single parameter and multiple parameters differently, then refer to the solution below:
let
API = [
{ actif: true, id: 8, creation_user: "David", date_creation: "févr 4 2022 12:17PM", description: "A description", version: "v1r1" },
{ actif: true, id: 10, creation_user: "Julien", date_creation: "févr 10 2022 12:17PM", description: "A description", version: "v1r2" },
{ actif: false, id: 20, creation_user: "Tom", date_creation: "févr 10 2022 12:17PM", description: "A description", version: "v1r2" },
],
Parameters = [
{ id: 10, name: "codeRR", type: "string" },
{ id: 20, name: "codeAA", type: "string" },
{ id: 20, name: "codeCC", type: "string" },
],
ParametersGroup = Parameters.reduce((r, p) => ((r[p.id] ??= []).push(p), r), {}),
APIWithParams = API.map((o) => {
const paramsForId = ParametersGroup[o.id];
return {
...o,
...(paramsForId && (paramsForId.length > 1 ? { parameters: paramsForId } : paramsForId[0])),
};
});
console.log(APIWithParams);
Note: Finding the parameter for an id
again and again is not optimal. Hence we've created an object beforehand and referenced it while adding the parameter information.
Other relevant documentations:
Upvotes: 1
Reputation: 15540
You're almost there. You can add extra logic for your map
to handle multiple and single parameters separately.
let API = [{
actif: true,
id: 8,
creation_user: "David",
date_creation: "févr 4 2022 12:17PM",
description: "A description",
version: "v1r1"
},
{
actif: true,
id: 10,
creation_user: "Julien",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
},
{
actif: false,
id: 20,
creation_user: "Tom",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
}
]
let Parameters = [{
id: 10,
name: "codeRR",
type: "string"
},
{
id: 20,
name: "codeAA",
type: "string"
},
{
id: 20,
name: "codeCC",
type: "string"
}
]
const result = API.map((data) => {
const updatedData = Object.assign({}, data)
const foundParameters = Parameters.filter(({
id
}) => id === data.id)
if (foundParameters.length === 0) {
return data
}
if (foundParameters.length === 1) {
return Object.assign(updatedData, foundParameters[0])
} else {
return Object.assign(updatedData, {
parameter: foundParameters.map(({
name,
type
}) => ({
name,
type
}))
})
}
});
console.log(result)
Upvotes: 1
Reputation: 7139
If the parameters have the same attributes they will be overwritten.
if you need both of them you need to store them in an array
like this
const decorate = (data, parameters) => data.map(d => ({...d, parameters: parameters.filter(({id}) => d.id === id)}))
let API = [
{
actif: true,
id: 8,
creation_user: "David",
date_creation: "févr 4 2022 12:17PM",
description: "A description",
version: "v1r1"
},
{
actif: true,
id: 10,
creation_user: "Julien",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
},
{
actif: false,
id: 20,
creation_user: "Tom",
date_creation: "févr 10 2022 12:17PM",
description: "A description",
version: "v1r2"
}
]
let Parameters = [
{
id: 10,
name: "codeRR",
type: "string"
},
{
id: 20,
name: "codeAA",
type: "string"
},
{
id: 20,
name: "codeCC",
type: "string"
}
]
console.log(decorate(API,Parameters ))
Upvotes: 1