[英]How to convert array of objects into nested array of objects?
我有一個具有以下結構的對象數組:
var items = [
{
attributes: [
{
type: "Size",
value: "Small"
},
{
type: "Color",
value: "Black"
}
]
},
{
attributes: [
{
type: "Size",
value: "Small"
},
{
type: "Color",
value: "White"
}
]
},
{
attributes: [
{
type: "Size",
value: "Medium"
},
{
type: "Color",
value: "Black"
}
]
},
{
attributes: [
{
type: "Size",
value: "Medium"
},
{
type: "Color",
value: "White"
}
]
}
];
我的目標是提取具有相同“類型”的所有“值”屬性。 例如,類型“大小”具有以下值:小,中。 之后,我要創建一個具有以下結構的新列表:
var results = [
{
type: "Size",
values: ["Small", "Medium"]
},
{
type: "Color",
values: ["White", "Black"]
}
];
這是我當前的代碼:
var results = items.map((item, index) => {
return item.attributes.map(attribute => {
let value = [];
value.push(attribute.value);
return {
type: attribute.type,
value: attribute.value
};
});
});
您可以使用reduce
和Set
type
映射為最終對象上的鍵,然后將值添加到相應的鍵中,因為我們只想保留唯一的值,因此我們使用Set
{type: { type, value }}
但是我們想要的格式是{ type, size}
所以我們使用Object.values()
從final
獲取{type, value}
,然后將其映射為所需格式 var items = [{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "White"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "White"}]}]; let final = items.reduce((op, {attributes}) => { attributes.forEach(({type, value}) => { op[type] = op[type] || {type, value: new Set()} op[type].value.add(value) }) return op },{}) let output = Object.values(final).map(({type, value}) => ({type, value:[...value]})) console.log(output)
您可以首先將結構簡化為[類型,值]對。 然后創建一個按類型作為鍵的地圖,以集合作為值(以確保值的唯一性),填充該地圖,最后將該地圖轉換為所需的結構:
var items = [{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Small"},{type: "Color",value: "White"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "Black"}]},{attributes: [{type: "Size",value: "Medium"},{type: "Color",value: "White"}]}]; const pairs = items.flatMap(({attributes}) => attributes.map(({type, value}) => [type, value])); const map = new Map(pairs.map(([type]) => [type, new Set])); pairs.forEach(([type, value]) => map.get(type).add(value)); const result = Array.from(map, ([type, values]) => ({ type, values: [...values] })); console.log(result);
var items = [ { attributes: [ { type: "Size", value: "Small" }, { type: "Color", value: "Black" } ] }, { attributes: [ { type: "Size", value: "Small" }, { type: "Color", value: "White" } ] }, { attributes: [ { type: "Size", value: "Medium" }, { type: "Color", value: "Black" } ] }, { attributes: [ { type: "Size", value: "Medium" }, { type: "Color", value: "White" } ] } ]; var temp={}; // temporarly holder items.forEach(function(item){ // iterate through each element item.attributes.forEach(function(attr){ // iterate through attributes of each element if (!temp[attr.type]) { temp[attr.type] = []; } // if this is the first time we encounter // this attribute, create a new placeholder if(temp[attr.type].indexOf(attr.value)<0) { // only add the attribute value if it was // not added before temp[attr.type].push(attr.value); }; }); }); var result = []; // create the output result array Object.keys(temp).forEach(function(key){ // iterate thought the keys of the temp object // add a new element with the properties congigured as desired result.push({type:key, values:temp[key]}); }); console.log(result);
var items = [ { attributes: [ { type: "Size", value: "Small" }, { type: "Color", value: "Black" } ] }, { attributes: [ { type: "Size", value: "Small" }, { type: "Color", value: "White" } ] }, { attributes: [ { type: "Size", value: "Medium" }, { type: "Color", value: "Black" } ] }, { attributes: [ { type: "Size", value: "Medium" }, { type: "Color", value: "White" } ] } ]; var results=[]; var type=[]; var values=[]; for(var i=0; i<items.length;i++){ var x=items[i].attributes; for(var j=0; j<x.length;j++){ var pos=type.indexOf(x[j].type); if(pos==-1){ type.push(x[j].type); values.push([]); pos=type.length-1; } if(values[pos].indexOf(x[j].value)==-1) values[pos].push(x[j].value); } } for(var i=0; i<type.length;i++){ results.push({type:type[i],values:values[i]}) } console.log(results);
您不想使用map,而是想要使用reduce。
items.reduce(
(acc, item) => {
item.attributes.forEach(
attribute => {
let type = acc.find(type => type.type == attribute.type);
if (!type) {
type = {type: attribute.type, values: []};
acc.push(type);
}
if (!type.values.includes(attribute.value)) {
type.values.push(attribute.value);
}
}
);
return acc;
}, []
)
這將產生稍微不同的輸出。 一個對象而不是對象數組。
let result = {};
items.forEach(item => item.attributes.forEach(att => {
if (result[att.type]) result[att.type].push(att.value);
else result[att.type] = [att.value];
}));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.