All files helpers.js

10.38% Statements 8/77
100% Branches 1/1
0% Functions 0/8
10.38% Lines 8/77

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 781x               1x               1x           1x     1x                 1x                       1x                                 1x                            
export function makeOutgoingEdges(arr) {
    return arr.reduce((edges, [from, to]) => {
        edges.has(from) || edges.set(from, new Set());
        edges.has(to) || edges.set(to, new Set());
        edges.get(from).add(to);
        return edges;
    }, new Map());
}
export function makeIncomingEdges(arr) {
    return arr.reduce((edges, [from, to]) => {
        edges.has(from) || edges.set(from, new Set());
        edges.has(to) || edges.set(to, new Set());
        edges.get(to).add(from);
        return edges;
    }, new Map());
}
export function getStartNodes(edges) {
    const incomingEdges = makeIncomingEdges(edges);
    const startNodes = [];
    incomingEdges.forEach((value, key) => value.size === 0 && startNodes.push(key));
    return startNodes;
}
export function makeNodesHash(arr) {
    return new Map(arr.map((item, i) => [item, i]));
}
export function uniqueNodes(arr) {
    const res = new Set();
    for (let i = 0, len = arr.length; i < len; i++) {
        const edge = arr[i];
        res.add(edge[0]);
        res.add(edge[1]);
    }
    return [...res];
}
export function visitDepthFirst({ node, adjacencyMap, }) {
    const visited = new Set();
    const stack = [node];
    let cur = node;
    while (cur) {
        visited.add(cur);
        const neighbors = [...adjacencyMap.get(cur)];
        stack.push(...neighbors.filter((item) => !visited.has(item)).reverse());
        cur = stack.pop();
    }
    return visited;
}
export function getAdjacencyMapOfIndirectedGraph(edges) {
    return edges.reduce((acc, [from, to]) => {
        [
            [from, to],
            [to, from],
        ].forEach(([node, neighbor]) => {
            const neighbors = acc.get(node);
            if (neighbors) {
                neighbors.add(neighbor);
            }
            else {
                acc.set(node, new Set([neighbor]));
            }
        });
        return acc;
    }, new Map());
}
export function groupByComponents({ edges }) {
    const adjacencyMap = getAdjacencyMapOfIndirectedGraph(edges);
    const nodes = uniqueNodes(edges);
    const components = [];
    const visitedNodes = new Set();
    let currentNode = nodes[0];
    while (visitedNodes.size < nodes.length) {
        const visited = visitDepthFirst({ adjacencyMap, node: currentNode });
        components.push(visited);
        visited.forEach((node) => visitedNodes.add(node));
        currentNode = nodes.find((node) => !visitedNodes.has(node));
    }
    return components;
}