自动将json属性parsing为一个新的对象

我有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是手动添加{}的“假”对象,所以它被识别为一个string:

 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",}' } 

你能帮助我如何使项目对象成为一个真正的对象,所以我可以自动parsingJSON我想要的格式?

所以基本上你想创build一个给定所有嵌套对象的“值”属性的地图。 这意味着你必须过滤出原始对象的键不是对象或没有“价值”道具。 这是我将如何做到这一点(我已经使用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; }, {}); } 

更新:我也创build了一个npm包,它叫做json2kv ,你可以在这里find它的源代码

原始的JavaScript代码可以改变, if约束来处理数组,它不会处理数组,如果你的数据字段不是arrays它正常工作

如果你的json有数组,它将会非常复杂(而不是关于你想要的代码)。 另一个proplem是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" }