我正在标题上显示的数据格式转换中工作,但我不知道如何弄清楚。我尝试编写打击代码以添加第二维数组的变量名称:
const data = [
{ id: 1, var1: 'val1', var2: 'val2', varX: ['time1', 'time2', 'time3'] },
{ id: 2, var1: 'val2', var2: 'val3', varX: ['time4', 'time5', 'time6'] },
];
const test = data.map((o) => o.varX);
for (i = 0; i < test.length; i++) {
const test2 = test[i].reduce((res, cur, idx) => {
res[`varX${idx}`] = cur;
return res;
}, {});
console.log(test2);
}
但是我期望的结果应该是:
[{id:1, var1:val1, var2:val2, varX1:time1, varX2:time2, varX3:time3},{id:2, var1:val2, var2:val3, varX1:time4, varX2:time5, varX3:time6}]
有人可以指导我如何转换数据吗?
答案 0 :(得分:0)
由于test
中的第一个映射,您仅对varX
的值进行操作。您只需添加其他操作即可将原始data[i]
对象与新的缩小的varX
对象合并。
const data = [
{ id: 1, var1: 'val1', var2: 'val2', varX: ['time1', 'time2', 'time3'] },
{ id: 2, var1: 'val2', var2: 'val3', varX: ['time4', 'time5', 'time6'] },
];
const test = data.map((o) => o.varX);
for (i = 0; i < test.length; i++) {
const test2 = test[i].reduce((res, cur, idx) => {
res[`varX${idx}`] = cur;
return res;
}, {});
// exclude varX and merge your new varX${i} back into data[i]
const {varX, ...test3} = Object.assign(data[i], test2);
console.log(test3);
}
转换就地代码。我故意避免使用reduce,因为语法变得不易理解,并且增加了性能开销。缺点是此代码使原始data
发生突变(就地转换数据)。通过在映射时创建对象val
的副本,可以轻松缓解这种情况。
[1,2,3,4,5,6].forEach( i => eval(`time${i} = "time${i}";val${i} = "val${i}"`) );
const data = [{id:1, var1:val1, var2:val2, varX:[time1, time2, time3]}, {id:2, var1:val2, var2:val3, varX:[time4, time5, time6]}]
data.forEach((val, i)=>{
val.varX.forEach( (X,i) => val[`varX${i}`]=X );
delete val.varX;
console.log(val);
return val;
});
console.log(data);
我在下面使用reduce和spread语法创建了一个版本。您可以将传播语法视为将属性复制到正在生成的新对象的简单操作。我已使用解构语法将varX
与其余属性隔离,并将它们放在varX
和noVarX
中。
这还具有深度复制的优点,除了数据中最终外部引用的对象之外。
[1,2,3,4,5,6].forEach( i => eval(`time${i} = "time${i}";val${i} = "val${i}"`) );
const data = [{id:1, var1:val1, var2:val2, varX:[time1, time2, time3]}, {id:2, var1:val2, var2:val3, varX:[time4, time5, time6]}]
const expanded = data.map(val => {
const {varX, ...noVarX} = val;
return {
...noVarX,
...varX.reduce( (res, cur, idx) =>
({ ...res, [`varX${idx}`]: cur }), {})
};
});
console.log(expanded);
答案 1 :(得分:0)
您的代码存在的问题是,通过仅映射具有varX
的值,您会从data
中引出不是varX
的属性。然后,您可以很好地减少它们,但是您必须将“剩余”属性合并到新对象中,这对我来说有点麻烦。相反,您可以执行以下操作:
const data = [
{ id: 1, var1: "val1", var2: "val2", varX: ["time1", "time2", "time3"] },
{ id: 2, var1: "val2", var2: "val3", varX: ["time4", "time5", "time6"] },
];
const test = data.map((o) => {
return Object.entries(o).reduce((p, [k, v]) => {
if (k === "varX") {
for (let index = 0; index < v.length; index++) {
p[`varX${index + 1}`] = v[index];
}
} else {
p[k] = v;
}
return p;
}, {});
});
console.log(test);
首先,您映射数据对象,然后为每个对象减少其键/值对,并检查属性是否为varX
,如果是,则遍历数组并将其分配给新对象。 varX${index + 1}
,因为您希望第一个属性为varX1
,否则您只需保留相同的键/值对。
答案 2 :(得分:0)
在使用第二种reduce
方法将varX
替换为新对象之后,您需要在map()
方法而不是数组中创建对象
const data = [{'id':1, 'var1':'val1', 'var2':'val2', 'varX':['time1', 'time2', 'time3']},
{'id':2, 'var1':'val2', 'var2':'val3', 'varX':['time4', 'time5', 'time6']}]
const test = data.map(item => item.varX);
const test2 = {}
for (i = 0; i < test.length; i++) {
test2[i] = test[i].reduce((accum, item, index) => {
return { ...accum, [`varX${index}`]: item};
}, {});
}
const dataX = data.map((item, index) => {
delete item.varX
return { ...item, ...test2[index] }
});
console.log(dataX)