合并两个nodelist而不重复

时间:2013-10-13 15:02:18

标签: javascript arrays merge nodes

我尝试将两个节点列表合并为一个,但是当我在一个数组中连接时,有两次同一个节点。如果要插入的节点已存在于数组中,Concat不会搜索...

var firstNodelist = document.querySelectorAll("#outter, #inner");
var finalArray = new Array();

for (var i = 0; i < firstNodelist.length; i++) {

    var secondNodelist = firstNodelist[i].querySelectorAll("div");

    var firstArray = new Array();

    for (var x = 0; x < secondNodelist.length; x++) {

        firstArray.push(secondNodelist[x]);

    }

    finalArray = finalArray.concat(firstArray)

}

console.log("FINAL", finalArray);

The jsfiddle exemple

1 个答案:

答案 0 :(得分:3)

不要在循环中构建第二个不必要的数组,只需使用该内部循环来检查节点是否已经在数组中(Array#indexOf在所有现代浏览器中)并且只在不是

var firstNodelist = document.querySelectorAll("#outter, #inner");
var finalArray = []; // `[]` rather than `new Array()`

for (var i = 0; i < firstNodelist.length; i++) {

    var secondNodelist = firstNodelist[i].querySelectorAll("div");

    for (var x = 0; x < secondNodelist.length; x++) {

        // Get this node
        var node = secondNodeList[x];

        // Is it in the array already?
        if (finalArray.indexOf(node) === -1) {
            // No, put it there
            finalArray.push(node);
        }

    }
}

console.log("FINAL", finalArray);

请务必测试您的目标环境,以确保他们有Array#indexOf


说完后,对于特定的情况有更好的方法:Live Example | Live Source

var finalArray = Array.prototype.slice.call(
    document.querySelectorAll("#outter div, #inner div")
);

...由于querySelectorAll不会多次包含同一个节点,即使#inner位于#outter内(反之亦然)。 (Array.prototype.slice.call(someObject)是从任何类似数组的对象中获取真实数组的技巧。)