简体   繁体   中英

Find cyclic dependency without using graph in Map of array

I have an object like following:

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

I have to find map of entities cyclic without converting it to graph.

Like output will be like following:

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']},
};

I tried with following:

 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); 

Is there any other way to make it more performant. I think using JSON.stringify in itrative manner with try catch block might be also a way. but I'm not sure it will be more/less performant.

You could take a function for checking the cyclic nature and store visited nodes to prevent to loop forever.

The result is an object with starting keys and their nodes which are cyclic. The wanted format is left as exercise to the reader.

 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; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM