【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

回到顶部