在JS中将嵌套JSON转换为简单JSON



我想转换像这样的嵌套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()结合使用,检查值的类型

  • 请注意,解决方案期望的数据值类型为stringobject
  • 代码:

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);

最新更新