【Web前端问题】数据格式的转换问题
问题描述
const data = [ {
month:'2019-01',
list:[
{name:'语文',share:98},
{name:'数学',share:89},
{name:'其它',share:45},
]
},
{
month:'2019-02',
list:[
{name:'外语',share:34},
{name:'数学',share:56},
{name:'其它',share:33},
]
}
]
转换成
[ ['month','2019-01','2019-02'],
['语文',98,0],
['数学',89,56],
['外语',0,34],
['其它',45,33],
]
问题出现的环境背景及自己尝试过哪些方法
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
我考虑先把所有科目都找出来
// 取出所有类目 const ALL = [
...new Set(
monthList &&
monthList
.map(i => i.list)
.flat(1)
.map(j => j.name)
),
];
想的是
ALL.map()结果发现至少要map三层 复杂度很高
有没有算法简单点的处理方式
回答:
const data = []; //原数据const result = data.reduce(({months, names}, {month, list}, index) => {
months.push(month);
list.forEach(v => {
if (!names[v.name]) names[v.name] = {};
names[v.name][month] = v.share;
});
if (index === data.length - 1) {
return [
['month', ...months],
...Object.keys(names).map(name => [
name, ...months.map(_month => names[name][_month] || 0),
]),
];
}
return {months, names};
}, {months: [], names: {}});
console.log(result);
写完发现这个解决方式复杂度还是挺高的,应该还有更优解
再提供一个解决方式,先提取names
,逻辑简单得多
const result = data.reduce((ary, {month, list}) => { ary.forEach((arr, i) => {
let v = i ? list.find(v => v.name === arr[0]) : month;
arr.push(i ? (v ? v.share : 0) : v);
});
return ary;
}, [...new Set(['month', ...data.flatMap(v => v.list.map(v => v.name))])].map(v => [v]));
回答:
数据层次嵌套较深,应该是至少需要三层循环的,find也是一层。。。坐等大佬的简便方法
const data = [ {
month:'2019-01',
list:[
{name:'语文',share:98},
{name:'数学',share:89},
{name:'其它',share:45},
]
},
{
month:'2019-02',
list:[
{name:'外语',share:34},
{name:'数学',share:56},
{name:'其它',share:33},
]
}
]
let arr = [
['month']
]
data.forEach(month => {
arr[0].push(month.month)
month.list.forEach((name,index) => {
let find = arr.find(find => find[0] == name.name)
find ? find.push(name.share) : arr.push([name.name, name.share])
})
})
console.log(arr)
回答:
const temp = { 0:['语文'],
1:['数学'],
2:['其他']
}
const mArr = ['month']
data.forEach(d=>{
mArr.push(d.month)
d.list.forEach((l,i)=>{
temp[i].push(l.share)
})
})
let res = [mArr,temp[0], temp[1], temp[2]]
回答:
const data = [ {
month: '2019-01',
list: [
{ name: '语文', share: 98 },
{ name: '数学', share: 89 },
{ name: '其它', share: 45 }
]
},
{
month: '2019-02',
list: [
{ name: '外语', share: 34 },
{ name: '数学', share: 56 },
{ name: '其它', share: 33 }
]
}
]
function trans (data) {
const r = data.reduce((res, val, i) => {
res[0].push(val.month)
val.list.forEach(s => {
res[1][s.name] = res[1][s.name] || []
res[1][s.name][i] = s.share
let j = i - 1
while (!res[1][s.name][j] && j > -1) {
res[1][s.name][j--] = 0
}
})
return res
}, [['month'], {}])
return [r[0], ...Object.entries(r[1]).map(val => [val[0], ...val[1], ...new Array(r[0].length - val[1].length - 1).fill(0)])]
}
console.log(trans(data))
// [ [ 'month', '2019-01', '2019-02' ],
// [ '语文', 98, 0 ],
// [ '数学', 89, 56 ],
// [ '其它', 45, 33 ],
// [ '外语', 0, 34 ] ]
写完发现好蛋疼
回答:
个人理解的写法,示例如下,可以参考
const data = [ {
month:'2019-01',
list:[
{name:'语文',share:98},
{name:'数学',share:89},
{name:'其它',share:45},
]
},
{
month:'2019-02',
list:[
{name:'语文',share:34},
{name:'外语',share:34},
{name:'数学',share:56},
{name:'其它',share:33},
]
}
]
let monthArray = ['month'];
let objAll = {
'语文':['语文'],
'数学':['数学'],
'外语':['外语'],
'其它':['其它']
}
data.map((item,index)=>{
let {list} = item;
monthArray.push(item.month);
list.map(obj=>{
let {name,share} = obj;
objAll[name].push(share);
})
for(let key in objAll){
if(objAll[key].length==index+1){
objAll[key].push(0)
}
}
})
let success = [
monthArray
]
for(let key in objAll){
success.push(objAll[key])
}
console.log(success)
输出截图:
回答:
function zip(arr) { var ret = [];
if (arr instanceof Array) {
var obj = {};
for (var i = 0; i < arr.length; ++i) {
(obj.month || (obj.month = [])).push(arr[i].month);
for (var j = 0; j < arr[i].list.length; ++j) {
arr[i].list[j].name in obj || (obj[arr[i].list[j].name] = []);
obj[arr[i].list[j].name][i] = arr[i].list[j].share;
}
}
for (var key in obj) {
for (var i = 0; i < obj.month.length && key !== "month"; ++i) {
obj[key][i] == null && (obj[key][i] = 0);
}
ret.push([key].concat(obj[key]));
}
}
return ret;
}
console.log(zip(data));
回答:
至少三层循环。
第一次是data对象的循环;第二次是data.list的循环;
第三次是结果变为数组的循环,无论对象转数组,还是直接在数组找键,都必须经历一次;
下面虽然是三层循环,但是是单链的。一次执行完毕,没有嵌套循环。执行次数由data的数据数量及最后结果项的数组大小决定。
const data = [ {
month: "2019-01",
list: [
{ name: "语文", share: 98 },
{ name: "数学", share: 89 },
{ name: "其它", share: 45 }
]
},
{
month: "2019-02",
list: [
{ name: "外语", share: 34 },
{ name: "数学", share: 56 },
{ name: "其它", share: 33 }
]
}
];
const hash = {};
for (let i = 0, n = data.length; n > i; ) {
const {
[i++]: { list, month }
} = data;
(hash.month || (hash.month = ["month"]))[i] = month;
for (const { name, share } of list) {
(hash[name] || (hash[name] = [name].concat(new Array(n).fill(0))))[
i
] = share;
}
}
console.log(Object.values(hash));
以上是 【Web前端问题】数据格式的转换问题 的全部内容, 来源链接: utcz.com/a/143588.html