Javascript - 查找对称差异 - For循环错误

时间:2016-10-21 20:51:32

标签: javascript arrays for-loop

以下是我对FreeCodeCamp" Symmetric Difference"的解决方案。挑战。

正确的代码应该返回 2,3,4,6,7 。为什么我的代码返回 2,3,4,6

 function sym(args) {
    args = Array.from(arguments);
    var newArr = [];

    function removeFirstIndex() {
        for (var i = 0; i <= args[1].length; i++) {
            if (args[1].indexOf(args[0][i]) === -1) {
                newArr.push(args[0][i]);
            }
            if (args[0].indexOf(args[1][i]) === -1) {
                newArr.push(args[1][i]);
            }
        }
        args = args.splice(2);
        args.unshift(newArr);
        newArr=[];
    }
    while (args.length>1){
        removeFirstIndex();
    }
    args=args.reduce(function(a,b){
        return a.concat(b);
    });
    args=args.filter(function(elem,pos,self){
        return self.indexOf(elem)===pos && elem!==undefined;
    });
    return args.sort();
}
sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]); // should return 2, 3, 4, 6, 7

1 个答案:

答案 0 :(得分:3)

您的内部for循环将 i 运行到两个数组之一的长度,但您使用该索引来处理两个数组中的元素。如果它们的长度不同,您将跳过元素,或检查超出较短数组长度的值。

所以你需要将这个循环分成两个独立的循环:

    for (var i = 0; i <= args[0].length; i++) {
        if (args[1].indexOf(args[0][i]) === -1) {
            newArr.push(args[0][i]);
        }
    }
    for (var i = 0; i <= args[1].length; i++) {
        if (args[0].indexOf(args[1][i]) === -1) {
            newArr.push(args[1][i]);
        }
    }

这可以解决您的问题。

现在,您可以通过使用散列进行改进,您可以使用Set进行散列。

具有集合的解决方案:

这是使用散列执行操作的ES6代码。这样可以避免indexOf操作(时间复杂度为 O(n)),并使用Set.prototype.has代替({em> O(1)大多数实现):

&#13;
&#13;
function sym(...args) {
  return Array.from(
    args.map( a => new Set(a) )
      .reduce( (a, b) => new Set([...a, ...b].filter( x => !a.has(x) || !b.has(x) )) )
    ).sort();
}
var result = sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]); 
// should return 2, 3, 4, 6, 7

console.log(result);
&#13;
&#13;
&#13;