Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript组将键值链接到数组中_Javascript_Algorithm_Grouping_Graph Theory - Fatal编程技术网

Javascript组将键值链接到数组中

Javascript组将键值链接到数组中,javascript,algorithm,grouping,graph-theory,Javascript,Algorithm,Grouping,Graph Theory,嗨,我在json中有一个很长的键值对列表,包括key:value、key:value等等 car <--> wheel wheel <--> tyre bed <--> sheets guitar <--> strings guitar <--> pickup tyre <--> rubber 使用Javascript实现这一点的有效方法是什么?首先,我会将关系存储为数组,这样您就可以拥有重复的“键”;使用map和redu

嗨,我在json中有一个很长的键值对列表,包括key:value、key:value等等

car <--> wheel
wheel <--> tyre
bed <--> sheets
guitar <--> strings
guitar <--> pickup
tyre <--> rubber

使用Javascript实现这一点的有效方法是什么?

首先,我会将关系存储为数组,这样您就可以拥有重复的“键”;使用map和reduce的递归链式扩展器;基于等价性的过滤链

Array.prototype.getUnique = function(){
   var u = {}, a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(u.hasOwnProperty(this[i])) {
         continue;
      }
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a;
}
var links = {};
var pairs = [
    ["car", "wheel"],
    ["wheel", "tyre"],
    ["bed", "sheets"],
    ["guitar", "strings"],
    ["guitar", "pickup"],
    ["rubber", "tyre"],
    ["truck", "wheel"],
    ["pickup", "car"]
];
pairs.map(function(pair) {
    links[pair[0]] = links[pair[0]] || [];
    links[pair[1]] = links[pair[1]] || [];

    links[pair[0]].push(pair[1]);
    links[pair[1]].push(pair[0]);
});
var append = function(list) {
    var related = list.map(function(item) {
        return links[item];
    }).reduce(function(listA, listB) {
        return listA.concat(listB);
    }).filter(function(item) {
        // make sure related only includes new links
        return list.indexOf(item) == -1
    }).getUnique();

    return related.length ? append(list.concat(related)) : list.concat(related);
};
var branches = [];
for( var word in links ) {
    branches.push(append(links[word].concat(word)));
}
var compareArrays = function(listA, listB) {
    if( listA.length != listB.length ) return false;
    return listA.map(function(element) {
        if( listB.indexOf(element) == -1 ) return 0;
        return 1;
    }).filter(function(el) {
        return el == 1;
    }).length == listA.length;
};
var _branches = branches;
var chains = branches.filter(function(branch1, i) {     
    var isUnique = _branches.filter(function(branch2) {
        // are they equivalent
        return compareArrays(branch1, branch2);
    }).length == 1; 
    delete _branches[i];
    return isUnique;
});
Array.prototype.getUnique=function(){
变量u={},a=[];
对于(变量i=0,l=this.length;i
我会带上一张单词地图,链接它们当前所在的集合。map(一个javascript对象)具有接近O(1)个用于访问密钥的运行时,应该有助于提高性能。以@matt3141提议的相同格式开始:

var pairs = [
    ["car", "wheel"],
    ["wheel", "tyre"],
    ["bed", "sheets"],
    ["guitar", "strings"],
    ["guitar", "pickup"],
    ["rubber", "tyre"],
    ["truck", "wheel"],
    ["pickup", "car"]
];

var setsByWord = {};
for (var i=0; i<pairs.length; i++) {
    var pair = pairs[i];
    if (pair[0] in setsByWord && pair[1] in setsByWord) {
        // both words are already known
        if (setsByWord[pair[0]] === setsByWord[pair[1]]) {
             ; // We're lucky, they are in the same set
        } else {
             // combine the two sets
             var sets = [setsByWord[pair[0]], setsByWord[pair[1]]];
             var larger = sets[1].length > sets[0].length ? sets[1] : sets[0],
                 smaller = sets[+(larger===sets[0])];
             for (var j=0; j<smaller.length; j++)
                 setsByWord[smaller[j]] = larger;
             Array.prototype.push.apply(larger, smaller);
        }
    } else {
        // add the missing word to the existing set
        // or create a new set
        var set = setsByWord[pair[0]] || setsByWord[pair[1]] || [];
        if (!(pair[0] in setsByWord)) {
            set.push(pair[0]);
            setsByWord[pair[0]] = set;
        }
        if (!(pair[1] in setsByWord)) {
            set.push(pair[1]);
            setsByWord[pair[1]] = set;
        }
    }
}
return setsByWord;

如果您有一个有向图,并且希望按单词排列所有后续项,则可以使用以下方法:

var pairs = […],
    graph = pairs.reduce(function(map, pair) {
         (map[pair[0]] || (map[pair[0]] = [])).push(pair[1]);
         return map;
    }, {});

var successors = {};
for (var word in graph) (function getSuccessors(word) {
    if (word in successors)
        return successors[word];
    successors[word] = [true]; // some marker against circles
    return successors[word] = word in graph
        ? [].concat.apply(graph[word], graph[word].map(getSuccessors))
        : [];
})(word);
return successors;
如果您确定图形中没有圆,并且只需要路径初学者的列表,则可以添加以下内容:

var results = [];
for (var word in successors)
    for (var i=0; word in successors && i<successors[word].length; i++)
        delete successors[successors[word][i]];
for (var word in successors)
    results.push([word].concat(successors[word]));
return results;

// becomes:
[
   ["bed","sheets"],
   ["guitar","strings","pickup","car","wheel","tyre"],
   ["rubber","tyre"],
   ["truck","wheel","tyre"]
]
var结果=[];
for(后继字中的var字)

for(var i=0;word in continuencers&&iWhy标记?这与Java编程语言中的编程有什么关系?您有没有遇到问题的代码?json中的“in”是什么意思。你的意思是你有一个单一属性对象的数组吗?它是实际的JSON(一个需要解析的字符串)还是一个数组或对象?请显示你的实际输入。@elclans:“tyre”是我居住的地方的正确拼写…如果上面的示例输入中添加了“truck->wheel”项,你想做什么?可以“wheel”吗同时在两个输出数组中?(另外,我不认为人们真的对Java的事情感到愤怒-至少我没有。我们只是试图确保应用适当的标记,这就是我删除Java标记的原因。如果你想把它放回原处,那很好,但也许可以编辑你的问题,用两种语言寻求解决方案…)如果你真的需要一个有效的算法,你要做的就是“划分一个无向和未加权的图”。存在高效且正确的语言不可知算法,您无需重新发明。这似乎给了我4个空数组和一个仅包含橡胶的数组。感谢大家的提醒,它现在完全可以工作了-至少在示例中是这样。有时关系相当深。我如何知道在match_链中循环多少次,以便它没有遗漏这些?它在所有链中循环,包括关系中的任何一对。我不理解这个问题。那么你是说这两个数组应该合并吗?看起来OP更希望只有唯一的集合,你可以看到我是如何在中用
comparararray
branchs.filter
等实现这一点的我的第一个解决方案集合是唯一的,第二种方法如果不是必须的,当然-OP需要更准确地解释他的需求。
var pairs = […],
    graph = pairs.reduce(function(map, pair) {
         (map[pair[0]] || (map[pair[0]] = [])).push(pair[1]);
         return map;
    }, {});

var successors = {};
for (var word in graph) (function getSuccessors(word) {
    if (word in successors)
        return successors[word];
    successors[word] = [true]; // some marker against circles
    return successors[word] = word in graph
        ? [].concat.apply(graph[word], graph[word].map(getSuccessors))
        : [];
})(word);
return successors;
var results = [];
for (var word in successors)
    for (var i=0; word in successors && i<successors[word].length; i++)
        delete successors[successors[word][i]];
for (var word in successors)
    results.push([word].concat(successors[word]));
return results;

// becomes:
[
   ["bed","sheets"],
   ["guitar","strings","pickup","car","wheel","tyre"],
   ["rubber","tyre"],
   ["truck","wheel","tyre"]
]