【问题标题】:Char Sequence to Hierarchical JSON - d3.sunburst字符序列到分层 JSON - d3.sunburst
【发布时间】:2016-04-08 19:06:32
【问题描述】:

我得到了许多不同的字符模式的数组,请参阅下面的data,我正在尝试将数据嵌套到分层 JSON 表单中,以便插入到旭日形可视化中。每个模式都由n 字符组成,尽管下面是 8 个字符。讨论想要的结果:

  1. 在级别 0,找出有多少个唯一字符。答案:['w', 'm']。
  2. 获取第一个键“w”并找到位于第 1 级的所有唯一字符,然后转到第 2 级,依此类推,直到到达模式的末尾,我们在该模式的末尾计算该唯一模式的大小。
  3. 对第二个键“m”重复 #2
  4. 将结果插入到rootchildren 属性中。

我能够为两级案例构建代码,并且随后可以通过大量嵌套进行更深层次的嵌套,但它会非常硬编码并且超级难以理解。有谁知道我可以递归地执行此操作或使用另一种可以解决它的模式?

所需的输出样本:

var root = {"name":"evt_seq","children":[{"name":"w","children":[{"name":"w","size":8},{"name":"k","size":1}]},{"name":"m","children":[{"name":"w","size":1}]}]}

两级嵌套(寻找n级嵌套)

"use strict";
var data = [{"match": ["w", "w", "l", "w", "w", "w", "t", "w"]}, {"match": ["w", "k", "w", "A", "w", "w", "w", "w"]},
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["w", "w", "w", "w", "w", "w", "w", "w"]},
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["m", "w", "v", "v", "t", "m", "l", "m"]},
{"match": ["w", "w", "w", "l", "w", "w", "l", "l"]}, {"match": ["w", "w", "z", "w", "w", "m", "l", "w"]},
{"match": ["w", "w", "w", "w", "w", "w", "w", "w"]}, {"match": ["w", "w", "m", "w", "l", "w", "w", "w"]}
];

var root = {
    "name": "evt_seq", children: []
};
// Get initial pattern
var groupedXs = _.groupBy(data, function (d) {
    return d.match[0];
});
_.forEach(_.keys(groupedXs), function (d) {
    let _x = groupedXs[d];
    let _groupedXs = _.groupBy(_x, function (f) {
        return f.match[1];
    });
    let _children = _.map(_.keys(_groupedXs), function (f) {
        return {'name': f, 'size': _groupedXs[f].length}
    });
    root.children.push({"name": d, children: _children});
});
console.log(JSON.stringify(root));

【问题讨论】:

    标签: javascript json node.js d3.js


    【解决方案1】:

    这绝对是用递归算法最好的解决方案。由于语法似乎不太重要,我只给出简短的伪代码:

    function subTree(inputs) {
        var children = []
        var leadingLetters = //map first letter from each array, remove duplicates
        for leadingLetter in leadingLetters {
            var matchingInputs = //filter inputs that match the first letter
            var reducedInputs = //copy of matchingInputs, but the first (matching) element is removed from each array
            children.push(subTree(reducedInputs))
        }
        return children
    }
    var root = subTree(data);
    

    我没有将空子数组视为 null,因为我不完全确定当您到达字符串末尾时会发生什么。无论哪种方式,这应该让你上路。 (PS 希望这不是家庭作业!=X)

    【讨论】:

    • 感谢@Acey 的帮助!
    【解决方案2】:

    @Acey - 很好的指导!有关完整工作的实施,请参见下文。再次感谢,这是一个个人项目,而不是家庭作业:)

    function subTree(inputs) {
        var children = [];
        var leadingLetters = _.uniq(_.map(inputs, function (d) {
            return d.match[0];
        })); //map first letter from each array, remove duplicates
        _.forEach(leadingLetters, function (leadingLetter) {
                var matchingInputs = _.filter(inputs, function (d) {
                    return d.match[0] == leadingLetter;
                }); //filter inputs that match the first letter
                var reducedInputs = _.map(matchingInputs, function (d) {
                    return {"match": d.match.slice(1, d.match.length)};
                }); //copy of matchingInputs, but the first (matching) element is removed from each array
                if (!reducedInputs[0].match.length) {
                    children.push({name: leadingLetter, size: reducedInputs.length});
                }
                else {
                    children.push({"name": leadingLetter, children: subTree(reducedInputs)});
                }
            }
        );
        return children
    }
    
    var root = subTree(data);
    

    【讨论】:

      猜你喜欢
      • 2017-01-30
      • 2014-08-26
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      相关资源
      最近更新 更多