【问题标题】:Find cyclic dependency without using graph in Map of array在数组的映射中不使用图形查找循环依赖
【发布时间】:2019-10-04 02:50:38
【问题描述】:

我有一个像下面这样的对象:

var myMap = {
    v1: ['v2', 'v4', 'v5'],
    v2: ['x', 'v4', 'y'],
    v3: ['v2', 'v4', 'v5'],
    v4: ['e', 'v1', 'v5'],
    v5: ['v2', 'v4', 'v3'],
};

我必须找到循环实体图而不将其转换为图形。

输出如下:

var myDep = {
    v1: {isCyclic: true, cyclicDependents: ['v4']},
    v2: {isCyclic: false, cyclicDependents: []},
    v3: {isCyclic: true, cyclicDependents: ['v5']},
    v4: {isCyclic: true, cyclicDependents: ['v1', 'v5']},
    v5: {isCyclic: true, cyclicDependents: ['v4', 'v3']},
};

我尝试了以下方法:

var graph = {
  v1: ["v2", "v4", "v5"],
  v2: ["x", "v4", "y"],
  v3: ["v2", "v4", "v5"],
  v4: ["e", "v1", "v5"],
  v5: ["v2", "v4", "v3"]
};

var myDep = {
  v1: { isCyclic: false, cyclicDependents: [] },
  v2: { isCyclic: false, cyclicDependents: [] },
  v3: { isCyclic: false, cyclicDependents: [] },
  v4: { isCyclic: false, cyclicDependents: [] },
  v5: { isCyclic: false, cyclicDependents: [] }
};

myDep = Object.keys(graph).reduce((a, b) => {
  graph[b] &&
graph[b].forEach(d => {
  if (graph[d] && ~graph[d].indexOf(b)) {
    a[b].isCyclic = true;
    a[b].cyclicDependents.push(d);
  }
});
  return a;
}, myDep);

console.log(myDep);

有没有其他方法可以提高性能。我认为以迭代方式使用 JSON.stringify 和 try catch 块可能也是一种方法。但我不确定它的性能会更高/更低。

【问题讨论】:

  • 您好,为什么要限制您的问题?为什么说“不将其转换为图形”?您是否有不想先转换为图表的原因?您是否已经知道如何从图表中做到这一点并正在寻找不同的方法?
  • @Ray Toal,感谢您的提问。是的,我对 Graph 有一点想法。我不想使用 Graph,因为它会引入额外的 LOC(图形、节点等的定义),并且在我的代码中它只需要一次,因此希望在低 LOC 中完成它以提高代码的可读性。

标签: javascript graph cyclic-dependency cyclic-graph


【解决方案1】:

您可以使用一个函数来检查循环性质并存储访问过的节点以防止永远循环。

结果是一个具有循环起始键及其节点的对象。想要的格式留给读者作为练习。

function isCyclic(node, target, [...visited] = []) {
    if (node === target) return true;
    if (visited.includes(node) || !myMap[node]) return false;
    visited.push(node);
    return myMap[node].some(n => isCyclic(n, target, visited));
}

var myMap = { v1: ['v2', 'v4', 'v5'], v2: ['x', 'v4', 'y'], v3: ['v2', 'v4', 'v5'], v4: ['e', 'v1', 'v5'], v5: ['v2', 'v4', 'v3'] },
    result = {};
   
Object.entries(myMap).forEach(([k, v]) => result[k] = v.filter(n => isCyclic(n, k)));

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

【讨论】:

    猜你喜欢
    • 2019-10-13
    • 1970-01-01
    • 2015-12-25
    • 2020-09-27
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    相关资源
    最近更新 更多