【问题标题】:Find the length of the longest chain in a hierarchy查找层次结构中最长链的长度
【发布时间】:2018-02-07 21:56:57
【问题描述】:

我有分层数据用于在我的应用程序中创建 svg。我需要找到该数据源中最长链的长度。我可以逐级遍历数据源,递归地深入其中读取_children,调用递归函数来计算级别,但我相信一定有更好的方法。这更加复杂,因为数据源可以从它以 _children 和 _parents 开始的节点开始双向。

var findChildren = function (ds, level) {
    if (!ds._children || ds._children.length == 0) {
        return level;
    }

    var longest = level + 1;
    ds._children.forEach(function (item) {
        var result = findChildren(item, level + 1);
        if (result > longest) {
            longest = result;
        }
    });
    return longest;
}

这是我目前使用的函数,有一个相同的函数检查ds._parents 以另一种方式,将一个结果作为另一个的起始级别传递。我只是确定一定有更好的方法......

例如,相同的数据可能有三种方式,具体取决于用户从何处打开树。

  1. {"number":1,"type":"Delivery","_parents":[{"number":1,"type":"Order","_parents":[{"number":1,"type":"Quote"}]}]}

  2. {"number":1,"type":"Order","_parents":[{"number":1,"type":"Quote"}], "_children":[{"number":1,"type":"Delivery"}]}

  3. {"number":1,"type":"Quote","_children":[{"number":1,"type":"Order","_children":[{"number":1,"type":"Delivery"}]}]}

【问题讨论】:

  • 你能分享一下“分层数据”吗?
  • "但我相信一定有更好的方法。"你为什么这么肯定?
  • deepestlongest 的拼写错误吗?如果不是,它来自哪里?
  • @ScottSauyet 是的,在我意识到我需要双向进行之前,我把它写成最深的最深层次,所以把它改成在两个方向上都更有意义的东西,最长。
  • 我重新打开了这个问题,因为这不完全是重复的:这个问题有 d3.js 标签,而 D3 有特定的方法。

标签: javascript d3.js hierarchy


【解决方案1】:

你说你...

需要找到该数据源中最长链的长度。

这是从根到数据结构中最深叶的长度。有方便的 D3 方法可以快速找到最深的叶子。

所以,假设我们有一个像this 这样的分层数据:

{
    "name": "Eve",
    "children": [{
        "name": "Cain"
    }, {
        "name": "Seth",
        "children": [{
            "name": "Enos"
        }, {
            "name": "Noam"
        }]
    }, {
        "name": "Abel"
    }, {
        "name": "Awan",
        "children": [{
            "name": "Enoch"
        }]
    }, {
        "name": "Azura"
    }]
}

当你将它传递给d3.hierarchy()...

var hierarchy = d3.hierarchy(data);

...它会自动在每个节点中创建一个名为depth 的属性:

node.depth - 根节点为零,每个后代增加一。

所以,我们只需要一个简单的函数来获得最大的depth 值。例如:

var longest = d3.max(hierarchy.descendants().map(function(d) {
    return d.depth
}));

这是一个演示:

var data = {
  "name": "Eve",
  "children": [{
    "name": "Cain"
  }, {
    "name": "Seth",
    "children": [{
      "name": "Enos"
    }, {
      "name": "Noam"
    }]
  }, {
    "name": "Abel"
  }, {
    "name": "Awan",
    "children": [{
      "name": "Enoch"
    }]
  }, {
    "name": "Azura"
  }]
};

var hierarchy = d3.hierarchy(data);
var longest = d3.max(hierarchy.descendants().map(function(d) {
  return d.depth
}));
console.log("The longest chain has " + (longest + 1) + " levels.")
<script src="https://d3js.org/d3.v4.min.js"></script>

【讨论】:

  • 这绝对看起来可以解决我一半的问题,问题是数据源有两种方式,我的数据源的“根”可能有_children 和/或_parents,是有什么办法可以同时处理吗?
  • 根没有父级。如果你的根有父母,那它就不是根!
  • 从技术上讲,数据是从所选基础对象向任一方向前进的两棵树...
  • @Andrew 在这种情况下,您必须共享数据。我建议您发布一个新问题,而不是编辑这个问题,其中包含数据(两棵树)和对问题的清晰描述。如果数据太大,创建两个简单的树作为示例。
  • 我在这个问题中添加了一个简短的数据示例,采用三种不同的可能配置,哪种配置取决于用户从哪里开始(如果从“订单”打开,他们会得到选项 2)
猜你喜欢
  • 2011-03-20
  • 1970-01-01
  • 2022-07-04
  • 2011-03-22
  • 2020-06-17
  • 2021-09-29
  • 2020-03-22
  • 2015-09-28
  • 2015-04-23
相关资源
最近更新 更多