2017-05-24 110 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);