问题描述
输入:
[{
"dimensions": [{
"name": "Size","value": "Size1"
},{
"name": "Color","value": "Color1"
},{
"name": "Pattern","value": "1"
}
],"link": "link","title": "title"
},{
"dimensions": [{
"name": "Size","value": "Size2"
},"value": "2"
}
],"link": "link1","value": "Color2"
},"value": "3"
}
],"title": "title"
}]
预期输出:
{
"levels":3,"level_1_name":"Size","level_2_name":"Color","level_3_name":"Pattern","data":[
{
"value":"Size1","data":[
{
"value":"Color1","data":[
{
"value":"1"
}
]
},{
"value":"Color2","data":[
{
"value":"4"
}
]
}
]
},{
"value":"Size2","data":[
{
"value":"Color1","data":[
{
"value":"3"
}
]
},{
"value":"Color2","data":[
{
"value":"2"
}
]
}
]
}
]
}
我已经尝试过类似的事情
for(index=0; index<data[0].dimensions.length - 1; index++) {
let temp = _(data).groupBy(function(o) {
return o.dimensions[index].value
})
let keys = Object.keys(temp)
addData(final,keys,temp)
}
obj["data"] = final
function addData(data,temp) {
if (data && data.length) {
return data.forEach(function(data1){
console.log(data1)
return addData(data1,temp)
})
} else {
let data_arr = []
if (Array.isArray(data)) {
keys.forEach(function(key) {
data.push({
value: key,data: temp[key]
})
})
} else {
keys.forEach(function(key) {
let data_obj = {}
data_obj['value'] = key
data_obj['data'] = temp[key]
data_arr.push(data_obj)
})
data["data"] = data_arr
}
}
}
我已经尝试根据预期输出格式化逻辑。它适用于2级输入数据集,但是编写的逻辑不适用于3级输入数据集。
此外,如果您可以提出任何算法来解决此问题,也会很有帮助。
谢谢!
解决方法
这是一个使用reduce()
的紧凑型解决方案。 (我已经编辑了输入以匹配您的预期输出。)
const source = [{
"dimensions": [{
"name": "Size","value": "Size1"
},{
"name": "Color","value": "Color1"
},{
"name": "Pattern","value": "1"
}
],"link": "link","title": "title"
},{
"dimensions": [{
"name": "Size","value": "Size2"
},"value": "Color2"
},"value": "2"
}
],"link": "link1","value": "4"
}
],"value": "3"
}
],"title": "title"
}];
const output = source.reduce((acc,{dimensions: dims}) => {
const levels = dims.length;
// initialize top-level keys based on first object
if (!acc.hasOwnProperty('levels')) {
acc.levels = levels;
dims.forEach((level,i) => acc[`level_${i+1}_name`] = level.name);
acc.data = [];
}
// iterate over dimension objects and merge with accumulator
let parent = acc.data;
dims.forEach((o,i) => {
let lvlObj = parent.find(e => e.value === o.value);
if (!lvlObj) {
lvlObj = i < levels - 1 ?
{value: o.value,data: []} :
{value: o.value};
parent.push({...lvlObj});
}
parent = lvlObj.data;
});
return acc;
},{});
console.log(output);