Javascript 用对象和重命名属性展平深度嵌套的数组
Javascript flatten deeply nested Array with objects and renaming properties
我再次对以下内容进行了扁平化和重命名。
我得到了什么:
test = [
{
date: '2020-03-30',
station: {
id: 0,
name: 'some description'
},
firstValues: [
{
result: 1,
type: 4,
max: 18,
min: 1,
},
{
result: 2,
type: 5,
max: 15,
min: 2,
}
],
lastValues: [
{
result: 1,
type: 3,
max: 17,
min: 1
},
{
result: 2,
type: 8,
max: 20,
min: 2
}
],
iD: 'xxx3',
count: 1
},
{
next object with same structure
}
]
我努力实现的目标:
test = [
{
date: '2020-03-30',
station: 'some description',
first_E01_result: 1,
first_E01_type: 4,
first_E01_max: 18,
first_E01_min: 1,
first_E02_result: 2,
first_E02_type: 5,
first_E02_max: 15,
first_E02_min: 2,
last_E01_result: 1,
last_E01_type: 3,
last_E01_max: 17,
last_E01_min: 1,
last_E02_result: 2,
last_E02_type: 8,
last_E02_max: 20,
last_E02_min: 2,
iD: 'xxx3',
count: 1
},
{
next object with same structure
}
]
我很清楚我的方法不对。到目前为止,我尝试了不同的方法,但无法正常工作。我再次陷入困境,无法找到正确的方法,因为我 运行 遇到两个主要问题:
如何区分第一个值和最后一个值? (切换大小写或如果和如果其他?)
和
如何从站对象访问名称 属性 并将其分配给“站”
的键
这是我的最后一种方法,它仍然缺少针对上述问题的正确代码:
convertTest(input) {
return input.map(obj => {
const obj1 = {};
const obj2 = {};
for (const prop in obj) {
if (obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
for (let i = 0; i < obj[prop].length; i++) {
for (const [key, value] of Object.entries(obj[prop][i])) {
const name = 'first_EO' + (i + 1).toString() + '_' + key;
obj2[name] = value;
}
}
} else {
obj1[prop] = obj[prop];
}
const dataconverted = Object.assign({}, obj1, obj2);
return dataconverted;
}
});
}
请试试这个。
test = test.map((elem) => {
elem.firstValues.forEach((child, index) => {
for(let key in child){
let v = `first_E${index+1}_${key}`
elem[v] = child[key];
}
})
elem.lastValues.forEach((child, index) => {
for(let key in child){
let v = `last_E${index+1}_${key}`
elem[v] = child[key];
}
})
elem['station'] = elem.station.name;
delete elem.firstValues;
delete elem.lastValues;
return elem;
})
你应该使用 Map 和 Object.keys
var test = [{"date":"2020-03-30","station":{"id":0,"name":"some description"},"firstValues":[{"result":1,"type":4,"max":18,"min":1},{"result":2,"type":5,"max":15,"min":2}],"lastValues":[{"result":1,"type":3,"max":17,"min":1},{"result":2,"type":8,"max":20,"min":2}],"iD":"xxx3","count":1}]
console.log(flatten(test));
function flatten(arr) {
return arr.map(el => ModifyObject(el))
}
function ModifyObject(el) {
const obj = {};
obj.date = el.date;
obj.iD = el.iD;
obj.count = el.count;
obj.station = el.station.name;
flattenObjectByProperty(obj, el, 'firstValues')
flattenObjectByProperty(obj, el, 'lastValues')
return obj;
}
function flattenObjectByProperty(obj, el, property) {
(el[property] || []).map((child, i) => {
Object.keys(child).forEach(key => {
obj[property + '_E' + i + '_' + key] = child[key]
});
});
}
除了具有特殊情况的第一层之外,您可以对所有其他嵌套对象采用递归方法。
var data = [{ date: '2020-03-30', station: { id: 0, name: 'some description' }, firstValues: [{ result: 1, type: 4, max: 18, min: 1 }, { result: 2, type: 5, max: 15, min: 2 }], lastValues: [{ result: 1, type: 3, max: 17, min: 1 }, { result: 2, type: 8, max: 20, min: 2 }], iD: 'xxx3', count: 1 }],
getPath = object => Object.entries(object).reduce((r, [k, v], i) => {
if (v && typeof v === 'object') {
r.push(...getPath(v).map(([left, right]) => [(Array.isArray(object) ? 'E' + (i + 1).toString().padStart(2, 0) : k) + '_' + left, right]));
} else {
r.push([k, v]);
}
return r;
}, []),
result = data.map(o => Object.fromEntries(Object.entries(o).reduce((r, [k, v]) => {
if (k === 'station') {
r.push([k, v.name]);
} else if (v && typeof v === 'object') {
if (k.endsWith('Values')) k = k.slice(0, -6);
r.push(...getPath(v).map(([left, right]) => [k + '_' + left, right]));
} else {
r.push([k, v]);
}
return r
}, [])));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以根据需要使用Array.prototype.reduce
来展平
const test = [
{
date: '2020-03-30',
station: {
id: 0,
name: 'some description'
},
firstValues: [
{
result: 1,
type: 4,
max: 18,
min: 1,
},
{
result: 2,
type: 5,
max: 15,
min: 2,
}
],
lastValues: [
{
result: 1,
type: 3,
max: 17,
min: 1
},
{
result: 2,
type: 8,
max: 20,
min: 2
}
],
iD: 'xxx3',
count: 1
}
];
const result = test.reduce((acc, curr) => {
const { firstValues, lastValues, ...rest } = curr;
const modifiedFirstValues = firstValues.reduce((r, c, i) => {
Object.entries(c).forEach(([key, value]) => {
const modifiedKey = `first_E${i + 1}_${key}`;
r[modifiedKey] = value;
});
return r;
}, Object.create(null));
const modifiedLastValues = lastValues.reduce((r, c, i) => {
Object.entries(c).forEach(([key, value]) => {
const modifiedKey = `last_E${i + 1}_${key}`;
r[modifiedKey] = value;
});
return r;
}, Object.create(null));
const finalObj = {
...rest,
...modifiedFirstValues,
...modifiedLastValues
};
acc.push(finalObj);
return acc;
}, []);
console.log(result);
我再次对以下内容进行了扁平化和重命名。 我得到了什么:
test = [
{
date: '2020-03-30',
station: {
id: 0,
name: 'some description'
},
firstValues: [
{
result: 1,
type: 4,
max: 18,
min: 1,
},
{
result: 2,
type: 5,
max: 15,
min: 2,
}
],
lastValues: [
{
result: 1,
type: 3,
max: 17,
min: 1
},
{
result: 2,
type: 8,
max: 20,
min: 2
}
],
iD: 'xxx3',
count: 1
},
{
next object with same structure
}
]
我努力实现的目标:
test = [
{
date: '2020-03-30',
station: 'some description',
first_E01_result: 1,
first_E01_type: 4,
first_E01_max: 18,
first_E01_min: 1,
first_E02_result: 2,
first_E02_type: 5,
first_E02_max: 15,
first_E02_min: 2,
last_E01_result: 1,
last_E01_type: 3,
last_E01_max: 17,
last_E01_min: 1,
last_E02_result: 2,
last_E02_type: 8,
last_E02_max: 20,
last_E02_min: 2,
iD: 'xxx3',
count: 1
},
{
next object with same structure
}
]
我很清楚我的方法不对。到目前为止,我尝试了不同的方法,但无法正常工作。我再次陷入困境,无法找到正确的方法,因为我 运行 遇到两个主要问题:
如何区分第一个值和最后一个值? (切换大小写或如果和如果其他?) 和 如何从站对象访问名称 属性 并将其分配给“站”
的键这是我的最后一种方法,它仍然缺少针对上述问题的正确代码:
convertTest(input) {
return input.map(obj => {
const obj1 = {};
const obj2 = {};
for (const prop in obj) {
if (obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
for (let i = 0; i < obj[prop].length; i++) {
for (const [key, value] of Object.entries(obj[prop][i])) {
const name = 'first_EO' + (i + 1).toString() + '_' + key;
obj2[name] = value;
}
}
} else {
obj1[prop] = obj[prop];
}
const dataconverted = Object.assign({}, obj1, obj2);
return dataconverted;
}
});
}
请试试这个。
test = test.map((elem) => {
elem.firstValues.forEach((child, index) => {
for(let key in child){
let v = `first_E${index+1}_${key}`
elem[v] = child[key];
}
})
elem.lastValues.forEach((child, index) => {
for(let key in child){
let v = `last_E${index+1}_${key}`
elem[v] = child[key];
}
})
elem['station'] = elem.station.name;
delete elem.firstValues;
delete elem.lastValues;
return elem;
})
你应该使用 Map 和 Object.keys
var test = [{"date":"2020-03-30","station":{"id":0,"name":"some description"},"firstValues":[{"result":1,"type":4,"max":18,"min":1},{"result":2,"type":5,"max":15,"min":2}],"lastValues":[{"result":1,"type":3,"max":17,"min":1},{"result":2,"type":8,"max":20,"min":2}],"iD":"xxx3","count":1}]
console.log(flatten(test));
function flatten(arr) {
return arr.map(el => ModifyObject(el))
}
function ModifyObject(el) {
const obj = {};
obj.date = el.date;
obj.iD = el.iD;
obj.count = el.count;
obj.station = el.station.name;
flattenObjectByProperty(obj, el, 'firstValues')
flattenObjectByProperty(obj, el, 'lastValues')
return obj;
}
function flattenObjectByProperty(obj, el, property) {
(el[property] || []).map((child, i) => {
Object.keys(child).forEach(key => {
obj[property + '_E' + i + '_' + key] = child[key]
});
});
}
除了具有特殊情况的第一层之外,您可以对所有其他嵌套对象采用递归方法。
var data = [{ date: '2020-03-30', station: { id: 0, name: 'some description' }, firstValues: [{ result: 1, type: 4, max: 18, min: 1 }, { result: 2, type: 5, max: 15, min: 2 }], lastValues: [{ result: 1, type: 3, max: 17, min: 1 }, { result: 2, type: 8, max: 20, min: 2 }], iD: 'xxx3', count: 1 }],
getPath = object => Object.entries(object).reduce((r, [k, v], i) => {
if (v && typeof v === 'object') {
r.push(...getPath(v).map(([left, right]) => [(Array.isArray(object) ? 'E' + (i + 1).toString().padStart(2, 0) : k) + '_' + left, right]));
} else {
r.push([k, v]);
}
return r;
}, []),
result = data.map(o => Object.fromEntries(Object.entries(o).reduce((r, [k, v]) => {
if (k === 'station') {
r.push([k, v.name]);
} else if (v && typeof v === 'object') {
if (k.endsWith('Values')) k = k.slice(0, -6);
r.push(...getPath(v).map(([left, right]) => [k + '_' + left, right]));
} else {
r.push([k, v]);
}
return r
}, [])));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以根据需要使用Array.prototype.reduce
来展平
const test = [
{
date: '2020-03-30',
station: {
id: 0,
name: 'some description'
},
firstValues: [
{
result: 1,
type: 4,
max: 18,
min: 1,
},
{
result: 2,
type: 5,
max: 15,
min: 2,
}
],
lastValues: [
{
result: 1,
type: 3,
max: 17,
min: 1
},
{
result: 2,
type: 8,
max: 20,
min: 2
}
],
iD: 'xxx3',
count: 1
}
];
const result = test.reduce((acc, curr) => {
const { firstValues, lastValues, ...rest } = curr;
const modifiedFirstValues = firstValues.reduce((r, c, i) => {
Object.entries(c).forEach(([key, value]) => {
const modifiedKey = `first_E${i + 1}_${key}`;
r[modifiedKey] = value;
});
return r;
}, Object.create(null));
const modifiedLastValues = lastValues.reduce((r, c, i) => {
Object.entries(c).forEach(([key, value]) => {
const modifiedKey = `last_E${i + 1}_${key}`;
r[modifiedKey] = value;
});
return r;
}, Object.create(null));
const finalObj = {
...rest,
...modifiedFirstValues,
...modifiedLastValues
};
acc.push(finalObj);
return acc;
}, []);
console.log(result);