我想转换像这样的嵌套JSON
{
"dateSession": "14/11/2022",
"HRdata": {
"1": 86,
"2": 88,
"3": 86,
"4": 85
},
"SPO2data": {
"1": 98,
"2": 97,
"3": 97,
"4": 96
}
}
变成这样:
{
"dateSession": "14/11/2022",
"HRdata-1": 86,
"HRdata-2": 88,
"HRdata-3": 86,
"HRdata-4": 85,
"SPO2data-1": 98,
"SPO2data-2": 97,
"SPO2data-3": 97,
"SPO2data-4": 96,
}
,其中嵌套对象中的每个字段将被命名为field+key,代表其实际路径。
我想生成一个csv与所有的数据,所以首先,我需要一个简单的json数组导出以及。
可以将Object.entries()与Array.prototype.reduce()结合使用,检查值的类型
- 请注意,解决方案期望的数据值类型为
string
和object
代码:
const data = {"dateSession": "14/11/2022","HRdata": {"1": 86,"2": 88,"3": 86,"4": 85},"SPO2data": {"1": 98,"2": 97,"3": 97,"4": 96}}
const result = Object.entries(data).reduce((a, [k, v]) => {
typeof v === 'object'
? Object.entries(data[k]).forEach(([n, v]) => (a[`${k}-${n}`] = v))
: (a[k] = v)
return a
}, {})
console.log(result)
const data = {
dateSession: '14/11/2022',
HRdata: {
1: 86,
2: 88,
3: 86,
4: 85,
},
SPO2data: {
1: 98,
2: 97,
3: 97,
4: 96,
},
}
const flattenedData = {}
const flatten = (obj, oldName = '') => {
//we are counting on the fact that we will get an object at first - you can add a condition to check it here
const entries = Object.entries(obj)
//iterate through the object. If we are encountering another object - send it again in recursion. If it's a value - add it to the flattened object
for (const [key, value] of entries) {
typeof value === 'object' && !Array.isArray(value)
? flatten(value, key + '-')
: (flattenedData[oldName + key] = value)
}
}
flatten(data)
console.log(flattenedData)
您基本上需要运行自己的解析器并手动映射键。一个递归函数应该在这里完成这个技巧,你检查typeof key === 'object' && !Array.isArray(key)
作为条件,以便递归回调并映射出新的/最终对象。
这是一个非常快速/肮脏/未经测试的例子…
let result = {};
const keysToMap = ['HRdata', 'SPO2data'];
let currKey = '';
const mapJson = (jsonData) => {
const keys = Object.keys(jsonData);
keys.forEach(key => {
if (typeof jsonData[key] === 'object' && !Array.isArray(jsonData[key])) {
currKey = key;
mapJson(jsonData[key];
} else {
if (isNaN(key)) {
result[key] = jsonData[currKey][key];
} else {
result[`${currKey}-${key}`] = jsonData[currKey][key];
}
}
});
});
上面的代码可以用许多更好的方式重构,但这是我能想到的最快的方式,这样我就可以重新开始工作了。
还是——上面的内容没有经过测试。它并不完美,但它传达了主要思想:
- 映射出对象
- 有一些方法来识别你在一个需要被平化的键上(这可以是查找,或者你可能想要想出的其他更聪明的评估)
- 当你遇到一个需要平化的键时,发出回调并让递归为你完成工作
我的解决方案的想法不是让它漂亮或性能,而是向您解释您想要做什么,只需浏览一下它。
上面的主要问题是它不能处理比你布置的更多的维度。如果你想这样做,你就必须重新评估解决方案,并做得更好。
同样,这也不是一个很好的O(n)解决方案。我相信还有更好的。但是,这只是一个开始,所以你可以重构到你想要的最终解决方案。
我已经为这种转换编写了递归代码,以便高度嵌套的对象也可以根据您的要求进行转换。代码如下所示:
const obj = {
"dateSession": "14/11/2022",
"HRdata": {
"1": 86,
"2": 88,
"3": 86,
"4": 85
},
"SPO2data": {
"1": 98,
"2": 97,
"3": 97,
"4": 96,
}
};
let newObj = {};
function modifyJson(obj, newObj, count, upperKey) {
for (const key of Object.keys(obj)) {
if (typeof obj[key] === 'object') {
newObj = modifyJson(obj[key], newObj, count + 1, key);
} else if (count > 0) {
newObj[`${upperKey}-${key}`] = obj[key];
} else {
newObj[key] = obj[key];
}
}
return newObj;
}
newObj = modifyJson(obj, {}, 0, '');
console.log(newObj);
试试这个:
const obj = {
"dateSession": "14/11/2022",
"HRdata": {
"1": 86,
"2": 88,
"3": 86,
"4": 85
},
"SPO2data": {
"1": 98,
"2": 97,
"3": 97,
"4": 96
}
};
const finalObj = {};
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') {
Object.keys(obj[key]).forEach(innerObjKey => {
finalObj[`${key}-${innerObjKey}`] = obj[key][innerObjKey]
})
} else {
finalObj[key] = obj[key]
}
});
console.log(finalObj);