Reputation: 586
i do have an object coming from an API like this:
this.Variations = [
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "P"},
{name: "Tecido", option: "Algodao"},
],
id : 1
},
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "P"},
{name: "Tecido", option: "Elastano"},
],
id : 2
},
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "M"},
{name: "Tecido", option: "Algodao"},
],
id : 3
}, ...
and i have to generate a nested array from it, in order to create the experience i need, which is the user selecting attributes one by time, and loading the possible options.
I am struggling with this for a long time now and got nowhere.
I believe I need an array similar to that:
array['Preto']['P']['Algodao'] = info;
array['Preto']['P']['Elastano'] = info;
array['Preto']['M']['Algodao'] = info;
Any tips on how to do that?
Upvotes: 1
Views: 762
Reputation: 14221
This code works regardless of the number of items in attributes
arrays:
var Variations = [
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "P"},
{name: "Tecido", option: "Algodao"},
{name: "Foo", option: "Bar"},
],
id : 1
},
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "P"},
{name: "Tecido", option: "Elastano"},
],
id : 2
},
{
attributes: [
{name: "Cor", option: "Preto"},
{name: "Tamanho", option: "M"},
{name: "Tecido", option: "Algodao"},
],
id : 3
}];
const getLevelValue = (rec, att, index) => index === rec.attributes.length - 1 ? rec.id : {},
getData = variations => variations.map(rec => rec.attributes.
reduce(({acc, current}, att, index) =>
(current = current ? current[att.option] = getLevelValue(rec, att, index) :
acc[att.option] = getLevelValue(rec, att, index), {acc, current}),
{acc: {}}).acc);
console.log(getData(Variations));
Upvotes: 1
Reputation: 386560
You could iterate the array and the attributes for a nested object and assign a value at the leaves.
var data = [{ attributes: [{ name: "Cor", option: "Preto" }, { name: "Tamanho", option: "P" }, { name: "Tecido", option: "Algodao" }], id: 1 }, { attributes: [{ name: "Cor", option: "Preto" }, { name: "Tamanho", option: "P" }, { name: "Tecido", option: "Elastano" }], id: 2 }, { attributes: [{ name: "Cor", option: "Preto" }, { name: "Tamanho", option: "M" }, { name: "Tecido", option: "Algodao" }], id: 3 }],
result = {};
data.forEach(function (a) {
a.attributes.reduce(function (r, b, i, bb) {
return r[b.option] = i + 1 === bb.length
? a.id
: r[b.option] || {};
}, result);
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 68393
Assuming that by info
you meant id
value, try this approach
var output = variations.map( s => ({ [s.attributes[0].option ] :
{ [s.attributes[1].option ] :
{ [ s.attributes[2].option] : s.id } } }) );
Demo
var variations = [{
attributes: [{
name: "Cor",
option: "Preto"
},
{
name: "Tamanho",
option: "P"
},
{
name: "Tecido",
option: "Algodao"
},
],
id: 1
},
{
attributes: [{
name: "Cor",
option: "Preto"
},
{
name: "Tamanho",
option: "P"
},
{
name: "Tecido",
option: "Elastano"
},
],
id: 2
},
{
attributes: [{
name: "Cor",
option: "Preto"
},
{
name: "Tamanho",
option: "M"
},
{
name: "Tecido",
option: "Algodao"
},
],
id: 3
}
];
var output = variations.map( s => ({ [s.attributes[0].option ] : { [s.attributes[1].option ] : { [ s.attributes[2].option] : s.id } } }) );
console.log( output );
Upvotes: 3