我有json
格式的传入数据,如下所示:
原始数据:
{
"data": [{
"id": "Device_6",
"type": "SensingDevice",
"Battery": {
"type": "Number",
"value": "4.08",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
},
"unit": {
"type": "Text",
"value": "voltage"
}
}
},
"DO": {
"type": "Number",
"value": "5.71",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
},
"unit": {
"type": "Text",
"value": "mg/l"
}
}
},
"Humidity": {
"type": "Number",
"value": "57.30",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
},
"unit": {
"type": "Text",
"value": "percent"
}
}
},
"PH": {
"type": "Number",
"value": "14.00",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
}
}
},
"temperature": {
"type": "Number",
"value": "41.00",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
},
"unit": {
"type": "Text",
"value": "celsius"
}
}
},
"waterTemperature": {
"type": "Number",
"value": "29.69",
"metadata": {
"timestamp": {
"type": "DateTime",
"value": "2017-11-09T14:49:02.00Z"
},
"unit": {
"type": "Text",
"value": "celsius"
}
}
}
}
],
"subscriptionId": "59d5eeec4f3db340052d618c"
}
出于特定的应用目的,我需要将此复杂JSON
转换为简单的key:value
格式。
所以我在节点js中使用node-json-transform包中的代码:
var map_data = {
list:'data',
item : { Battery: 'Battery.value',
DO: 'DO.value',
Humidity: 'Humidity.value',
PH: 'PH.value',
temperature: 'temperature.value',
waterTemperature: 'waterTemperature.value', },
};
console.log (map_data)
var dataTransform = DataTransform(data, map_data);
var data_result = dataTransform.transform();
输出看起来像我想要的那样:
[ { Battery: '4.08',
DO: '5.71',
Humidity: '57.30',
PH: '14.00',
temperature: '41.00',
waterTemperature: '29.69' } ]
但是现在,如果我不知道属性的名称怎么办? 所以我试着让它自动发现键:
var keys = Object.keys(data.data[0]);
var keysvalues = '';
for (i=2; i < keys.length; i++) {
keysvalues += keys[i]+':"'+ keys[i] + '.value",';
}
var item = '{'+keysvalues+'}';
var map_data = {
list:"data",
item,
};
var dataTransform = DataTransform(data, map_data);
var data_result = dataTransform.transform();
这不起作用,因为对象map_data.item
是一个“假”对象,我手动添加{}
,因此它被识别为字符串:
console.log(map_data)
{ list: 'data',
item: '{Battery:"Battery.value",DO:"DO.value",Humidity:"Humidity.value",PH:"PH.value",temperature:"temperature.value",waterTemperature:"waterTemperature.value",}' }
你能帮助我如何使项目对象成为一个真实的对象,这样我就能以我想要的格式自动解析JSON
吗?
答案 0 :(得分:2)
所以基本上你想创建一个给定所有嵌套对象的'value'属性的地图。这意味着您必须过滤掉原始对象中不是“对象”或没有“值”支柱的键。 这是我将如何做到的(我使用ES6来避免冗长)。
const isObject = (o) =>
o instanceof Object && o.constructor === Object;
const getSingleMap = (datum, prop) => {
const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
const obj = {};
mapKeys.forEach(key => {
obj[key] = datum[key][prop];
});
return obj;
}
const getMap = (rawData, prop) =>
rawData.data.map(datum => getSingleMap(datum, prop));
要使用它,只需拨打const res = getMap(rawData, 'value');
。
/*
res == [
{
"Battery": "4.08",
"DO": "5.71",
"Humidity": "57.30",
"PH": "14.00",
"temperature": "41.00",
"waterTemperature": "29.69"
}
];
*/
下面提供了一个更优雅的getSingleMap
实现。
getSingleMap = (datum, prop) => {
const mapKeys = Object.keys(datum).filter(key => isObject(datum[key]) && datum[key][prop]);
return mapKeys.reduce((acc, key) => {
acc[key] = datum[key][prop];
return acc;
}, {});
}
更新:我还创建了一个npm包,它叫做 json2kv ,你可以找到它的来源here
答案 1 :(得分:-1)
原始JavaScript代码
可以更改if
约束以处理 数组 如果您的DATA字段不是数组,它将无法处理数组
如果你的json中有数组,它将非常复杂(不仅仅是关于你想要的结果的代码)。
另一个问题是key : value
格式将覆盖您的许多信息
但是如果您想以任何方式执行此操作,只需执行以下操作:
function ToSimpleJson(json , result , prefix)
{
for(key in json)
{
if(typeof json[key]!="object" )
result[prefix+key] = json[key]
else if (!json[key].length) // Object
ToSimpleJson(json[key], result , (key+"."))
else // Array (But will Override if have more than 1 index)
{
json[key].forEach(function (x)
{
ToSimpleJson(x, result , (key + "."))
})
}
}
return result
}
并使用空结果和空前缀
调用函数ToSimpleJson(json , {} , "")
结果是:
{
"data.id" : "Device_6",
"data.type" : "SensingDevice",
"Battery.type" : "Number",
"Battery.value" : "4.08",
"timestamp.type" : "DateTime",
"timestamp.value" : "2017-11-09T14:49:02.00Z",
"unit.type" : "Text",
"unit.value" : "celsius",
"DO.type" : "Number",
"DO.value" : "5.71",
"Humidity.type" : "Number",
"Humidity.value" : "57.30",
"PH.type" : "Number",
"PH.value" : "14.00",
"temperature.type" : "Number",
"temperature.value" : "41.00",
"waterTemperature.type" : "Number",
"waterTemperature.value" : "29.69",
"subscriptionId" : "59d5eeec4f3db340052d618c"
}