【问题标题】:Build nested JSON from string of nested keys [duplicate]从嵌套键字符串构建嵌套 JSON [重复]
【发布时间】:2017-10-25 09:39:09
【问题描述】:

我有正在使用 nodeJS 读取的 csv 文件。我在阅读之前将每个文件转换为文本。

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

每一行看起来都像

data.location.degree.text=sometexthere

“=”之前的第一部分表示我的应用程序中 JSON 对象的索引。我的目标是解析这些数据并构建它的 JSON 表示,以便上面的行变成

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

使用 javascript/nodejs;如何将应该表示嵌套 JSON 键序列的字符串转换为像上面这样的 JSON 对象?

【问题讨论】:

    标签: javascript json node.js ecmascript-6


    【解决方案1】:

    您可以拆分路径并检查以下元素是否存在。如果没有将对象分配给新属性。

    然后返回属性的值。

    最后赋值。

    function setValue(object, path, value) {
        path = path.replace(/[\[]/gm, '.').replace(/[\]]/gm, ''); //to accept [index]
        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);

    【讨论】:

    • 这就像****一样优雅!
    • @Nina Scholz 如果可以的话,我会为此竖起数千个赞。谢谢!
    • 在函数顶部添加path = path.replace(/[\[]/gm, '.').replace(/[\]]/gm, '');以接受[n]参数。 .0[0] 工作相同
    • @SwiftNinjaPro,这是对的,但鉴于这个问题进行编辑毫无意义。
    【解决方案2】:

    // 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.handle.values.that.are_undefined=',
        'we.can.handle.values.that.contain_equals_signs=yes=we=can'
    ];
    
    // 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.shift()] = keyAndValue.join('=');
            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.join('=');
        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.handle.values.that.are_undefined=',
      'we.can.handle.values.that.contain_equals_signs=yes=we=can'
    ].forEach(x => pathToObject(res, x));
    
    console.log(res);

    【讨论】:

      猜你喜欢
      • 2019-08-20
      • 2017-07-30
      • 1970-01-01
      • 2022-08-18
      • 2016-02-12
      • 1970-01-01
      • 2021-08-22
      • 1970-01-01
      相关资源
      最近更新 更多