更有效的计算同现的方法

时间:2017-11-23 20:22:17

标签: javascript arrays

我想要想象一下人与人之间的关系网络。

我的数据如下:

let networkData = [
    ["John","Dylan","Brian"],
    ["Dylan","Brian"],
];

我想要一个像这样的输出:

let networkMatrix.links = [
    {source: "John",  target: "Dylan", weight: 1},
    {source: "John",  target: "Brian", weight: 1},
    {source: "Brian", target: "Dylan", weight: 2}
];

约翰和布莱恩分享一组,所以他们的体重是1.约翰和迪伦也是如此。由于迪伦和布莱恩分为两组,他们的关系的权重为2。

现在我认为我需要帮助。我这样做的方法是遍历networkData的每一行,然后遍历数组的每个元素。对于每个元素,遍历之后的所有元素,并在networkMatrix中增加其分数。这是我的代码。

var i = 0, j = 0;
networkData.map(function(d) {
    d.forEach(function(val, ind, tab) {
        for (let k = ind + 1; k < tab.length; k++) {
            while ((i = networkMatrix.person1.indexOf(val, i + 1)) != -1) {
                while ((j = networkMatrix.person2.indexOf(tab[k], j + 1)) != -1) {
                    if (i === j) {
                        networkMatrix.score[i]++;
                    }
                }
            }
        }
    })
});

这是一个jsfiddle:https://jsfiddle.net/0t81jg3b/2/

正如你所看到的,它甚至不适用于jsfiddle。但它在我的电脑上或多或少都有效,我不知道为什么:

enter image description here

如果觉得这对于如此简单的任务来说太复杂了,有人可以给我一些关于如何摆脱这种混乱的迹象吗?

1 个答案:

答案 0 :(得分:0)

你可以这样做:

  • 仅考虑源按字母顺序小于目标
  • 的名称对
  • 构建一个由source键入的地图,并为每个由目标键控的嵌套地图,并为这些嵌套键指定一个计数器。您可以使用ES6 Map,或者使用普通对象

&#13;
&#13;
const groupes = [
        ["John", "Dylan", "Brian"],
        ["Dylan", "Brian"],
        ["John", "Kate"]
    ],
    // Get unique list of names
    names = [...new Set([].concat(...groupes))],
    // Create a 2D-map with a counter set to zero
    map = new Map(names.map(name => [name, new Map(names.map(name2 => [name2, 0]))])),
    result = [];

// Count the pairs
for (const groupe of groupes) {
    for (const source of groupe) {
        const targetMap = map.get(source);
        for (const target of groupe) {
            if (source < target) targetMap.set(target, targetMap.get(target)+1);
        }
    }
}

// Convert nested maps to result structure
for (const [source, targetMap] of map.entries()) {
    for (const [target, weight] of targetMap.entries()) {
        if (weight) result.push({source, target, weight}); 
    }
}

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