2017-05-24 70 views
0

我使用nodeJS读取csv文件。我在阅读之前将每个文件转换为文本。从嵌套键字符串构建嵌套JSON

文件中的每一行都有以'='分隔的数据。

每一行看起来像

data.location.degree.text=sometexthere 

第一部分之前,“=”表示的索引来在我的应用程序JSON对象。我的目标是分析这些数据,并建立它的一个JSON表示,使得上面的线变得

data:{ 
    location:{ 
    degree:{ 
     text: 'sometexthere' 
    } 
    } 
} 

使用JavaScript /节点JS;如何将应该表示嵌套JSON键序列的字符串转换为上面的json对象?

回答

2

你可能分裂的道路,并作出检查,如果下面的元素存在。如果不将对象分配给新属性。

然后返回属性的值。

最后赋值。

function setValue(object, path, value) { 
 
    var keys = path.split('.'), 
 
     last = keys.pop(); 
 

 
    keys.reduce(function (o, k) { return o[k] = o[k] || {}; }, object)[last] = value; 
 
} 
 

 
var data = {}; 
 

 
setValue(data, 'location.degree.text', 'sometexthere'); 
 
console.log(data);

+0

这是优雅的为****! – vzwick

+0

@Nina Scholz如果可以的话,我会给这个成千上万的大拇指。谢谢! –

0

// result container 
 
var res = {}; 
 

 
// input data 
 
var inp = [ 
 
    'data.location.degree.text=sometexthere', 
 
    'data.otherLocation.degree.otherText=foo', 
 
    'data.location.degree.otherText=bar', 
 
    'we.can.do.undefined.values=' 
 
]; 
 

 
// recursive function 
 
var pathToObject = function(resultReference, path) 
 
{ 
 
    // split path on dots 
 
    // e.g. data.location.degree.text=sometexthere 
 
    // -> ["data", "location", "degree", "text=sometexthere"] 
 
    var splitPathParts = path.split('.'); 
 

 
    // if there is only one part, we're at the end of our path expression 
 
    // e.g. ["text=sometexthere"] 
 
    if (splitPathParts.length === 1){ 
 
     // split "text=sometexthere" into ["text", "sometexthere"] 
 
     var keyAndValue = splitPathParts[0].split('='); 
 

 
     // set foo = bar on our result object reference 
 
     resultReference[keyAndValue[0]] = keyAndValue[1]; 
 
     return; 
 
    } 
 
    
 
    // the first element of the split array is our current key 
 
    // e.g. for ["data", "location", "degree", "text=sometexthere"], 
 
    // the currentKey would be "data"; 
 
    var currentKey = splitPathParts.shift(); 
 

 
    // if our object does not yet contain the current key, set it to an empty object 
 
    resultReference[currentKey] || (resultReference[currentKey] = {}); 
 
    
 
    // recursively call ourselves, passing in 
 
    // the nested scope and the rest of the path. 
 
    // e.g. { data : {} } and 'location.degree.text=sometexthere' 
 
    pathToObject(resultReference[currentKey], splitPathParts.join('.')); 
 
} 
 

 
for (var i = 0; i < inp.length; i++) 
 
{ 
 
    pathToObject(res, inp[i]); 
 
} 
 
console.log(res);

ES6语法让事情变得更加紧凑:

'use strict'; 
 

 
const pathToObject = (resultReference, path) => { 
 
    let [currentKey, ...restOfPath] = path.split('.'); 
 
    
 
    if (restOfPath.length === 0) { 
 
    let [k, v] = currentKey.split('='); 
 
    resultReference[k] = v; 
 
    return; 
 
    } 
 

 
    resultReference[currentKey] || (resultReference[currentKey] = {}); 
 
    pathToObject(resultReference[currentKey], restOfPath.join('.')); 
 
} 
 

 
let res = {}; 
 

 
[ 
 
    'data.location.degree.text=sometexthere', 
 
    'data.otherLocation.degree.otherText=foo', 
 
    'data.location.degree.otherText=bar', 
 
    'we.can.do.undefined.values=' 
 
].forEach(x => pathToObject(res, x)); 
 

 
console.log(res);