将字符串数组转换为自定义结构

时间:2017-11-21 17:27:52

标签: javascript

我需要将这个字符串数组转换为特殊结构 https://github.com/jonmiles/bootstrap-treeview

这是我的输入字符串数组:

******************
"productone"
"productone\level2\level3"
"productwo"
"productwo\level2\level3\level4"
"productwo\level2\level3.1\level4\level5"
"productwo\level2\level3.2\level4\level5"

 so can you imagine this:

"memory"
"memory\ram"
"memory\ram\ddr\sodimm\533mhz\4gb"
"memory\ram\ddr\sodimm\533mhz\8gb"
"memory\ram\ddr\sodimm\533mhz\16gb"
"memory\ram\ddr\sodimm2\633mh\4gb
"memory\ram\ddr\sodimm2\633mh\16gb
"memory\disk"
and so on....
*******************

我需要这个输出(注意返回正确的顺序输出):

var jsondata = [
  {
  "text": "productone",
  "nodes":[ {"text": "level2",
            "nodes":[{"text": "level3"}]
           }]
  },
  {
  "text": "productwo",
   "nodes":[{"text": "level2"},
            "nodes":[{"text": "level3",
                        "nodes":[{text:level4}]
                    }]
            }]
  }    
}]

有什么建议吗?

4 个答案:

答案 0 :(得分:1)

我扔掉了我以前的答案,用这个替换它。

这应该完全符合您的要求。

Document Outline

我发现构建对象结构然后将其转换为您想要的格式要容易得多。这简化了解析算法,但每次都无法重建所有内容。

上面代码的结果如下:

var src = [
  "productone",
  "productone\\level2\\level3",
  "productwo\\level2\\level3\\level4",
  "productone\\level2\\dog",
  "productone\\level2\\dog\\bark",
  "productwo\\level2\\level3a\\level4a",
  "productwo\\level2\\level3\\level4\\level5",
  "productwo\\food\\desserts\\cookies",
  "productwo\\food\\desserts\\cakes",
  "productwo\\food\\desserts\\pies",
  "productone\\level2\\cat",
  "productone\\level2\\cat\\meow"
]

function tempToObj(temp) {
  var result = [];
  Object.keys(temp).forEach(
    function(key) {
      var obj = {
        text: key
      };

      var nodes = tempToObj(temp[key]);
      if (nodes.length > 0) {
        obj.nodes = nodes;
      }

      result.push(obj);
    }
  );

  return result;
}

function strsToObj(strList) {
  var result = [];
  var tempResult = {};

  function buildNode(parts, idx, obj) {
    var key = parts[idx];

    obj[key] = obj[key] || {};

    idx++;
    if (idx < parts.length) {
      buildNode(parts, idx, obj[key]);
    }
  }

  strList.forEach(
    function(str) {
      var parts = str.split('\\');
      buildNode(parts, 0, tempResult);
    }
  );

  return tempToObj(tempResult);
}

var obj = strsToObj(src);
console.log(JSON.stringify(obj,0,2));

答案 1 :(得分:1)

我已经解决了我的问题,我已经转换为Javacript纯代码了 Brandon Clapp article

答案 2 :(得分:0)

您可string#split array#map内的每个字符串,并使用array#reduceRight检查结果对象中的nodestext值。如果某个级别存在text密钥,请将您的对象重新分配到nodes密钥,并使用当前text值填充text密钥。

&#13;
&#13;
var strings = ["productone","productone\\level2\\level3","productwo\\level2\\level3\\level4"];

const result = strings.map(string => string.split('\\').reduceRight((r,text, index) => {
  if(r['text'])
    r['nodes'] = [Object.assign({}, r)];
  r['text'] = text;
  return r;
},{}));

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 3 :(得分:0)

您可以通过将给定的部分字符串作为嵌套对象的标识来获取具有嵌套方法的哈希表,以收集所有数据。

稍后此提案会删除不含内容的不需要的节点。

此方法适用于未分类的数据。

&#13;
&#13;
var array = ["productone", "productone\\level2\\level3", "productwo\\level2\\level3\\level4"],
    result = [],
    hash = { _: result };

array.forEach(function (a) {
    a.split('\\').reduce(function (r, k) {
        if (!r[k]) {
            r[k] = { _: [] };
            r._.push({ text: k, nodes: r[k]._ });
        }
        return r[k];
    }, hash);
});

result.forEach(function clean(o) {
    if (o.nodes.length) {
        o.nodes.forEach(clean);
    } else {
        delete o.nodes;
    }
});

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;