2016-01-04 83 views
0

我的功能需要接受任意数量的列表,然后输出它们的对称差异。 sym([1, 2, 3], [5, 2, 1, 4])应返回[3, 5, 4]sym([1, 2, 5], [2, 3, 5], [3, 4, 5]) should return [1, 4, 5]。我很困惑我的代码的结果 - 这返回一个空的数组。javascript查找对称差异

function isin(num,arra) 
{ 
    for (var i=0; i<arra.length; i++) 
    { 
    if (num == arra[i]) 
    { 
     return true; 
    } 
    } 
    return false; 
} 

function sym() 
{ 
    console.log("logging args"); 
    console.log(arguments); // logs [Array[3], Array[4]] 
    var syms = []; 
    for (var i=0; i<arguments.length-1; i++) 
    { 
    var ins = false; 
    for (var j=0; j<arguments[i].length; j++) 
    { 
     for (var k=i+1; k < arguments.length; k++) 
     { 
      if(isin(arguments[i][j], arguments[k])) 
      { 
      ins = true; 
      } 
     } 
    } 
    if (ins === false) 
    { 
     syms.push(arguments[i][j]); 
    } 
    } 
    return syms; 
} 
sym([1, 2, 3], [5, 2, 1, 4]); 
+1

有了更新的问题,是你仍然收到'未定义的错误? –

+0

不,但我的代码返回一个空数组 – kilojoules

+0

谢谢大家的帮助。最后要说明的是,这段代码并不包含所有列表在一组> 2列表中具有相同元素的情况。 – kilojoules

回答

2

编辑:添加一些代码 您的循环变量都是全局的,包括i。把var放在他们面前(至少在i之前),你就完成了。

以下获取两个集合的对称差异。我希望你能从那里开始。

function isin(num,arra) 
{ 
    for (var i=0; i<arra.length; i++) 
    { 
    if (num == arra[i]){return true;} 
    } 
    return false; 
} 

function sym() 
{ 
    var j,k,i,l; 
    var syms = []; 
    for (i=0; i<arguments.length; i++) 
    { 
    var ins = false; 

    for (k=i+1; k < arguments.length; k++){ 
     for (j=0; j<arguments[i].length; j++){ 
     if(!isin(arguments[i][j], arguments[k])) 
     { 
      syms.push(arguments[i][j]); 
     } 
     } 
     for (l=0; l<arguments[k].length; l++){ 
     if(!isin(arguments[k][l], arguments[i])) 
     { 
      syms.push(arguments[k][l]); 
     } 
     } 
    } 
    } 
    return syms; 
} 
sym([1, 2, 3], [5, 2, 1, 4]); 
+1

这是正确的答案。 –

+0

谢谢你的提示!这是我的代码中的一个主要问题。我的函数仍然没有像预期的那样运行(它返回一个未定义值的数组)。我已更新我的问题以纳入我的更改。 – kilojoules

+0

我看到你重用了变量'j',所以不要在循环中声明它们,而是在函数的开头声明它们。但是当你想使用它时,这个变量已经到了最后。所以不要在最后收集,但当你找到它们(在最内层的循环中)。你需要改变一下逻辑,例如:当你做一个'isin()'时,你会得到你需要放下的交叉点并保留其余部分。 – deamentiaemundi

1

我的代码返回未定义值

的数组这是因为当你推到syms,您的for循环与j变量已完成。所以它实际上是在j = <arguments[i].length(现在它真的是一个超出边界索引读取)。

if (ins === false) 
{ 
    syms.push(arguments[i][j]); # push "undefined" onto syms. 
} 

确保你把这块代码放在for (var j=0; j<arguments[i].length; j++)块内。

+0

我的推理是,如果i + 1超出索引,它将等于'arguments.length',在执行之前导致for循环退出。如果'i + 1> = arguments.length',for循环会执行吗? – kilojoules

+0

你完全正确,我的错误。你是否尝试过打印'arguments'数组('console.log(arguments)') - 你的数组索引是可以的,但是你的数组必须包含一个'undefined'。 –

+0

谢谢。我现在意识到我的通用算法是有缺陷的,但是这解决了我的具体问题。 – kilojoules

1

为了解决多个阵列的对称差,我们可以通过设计,它返回两个阵列

对称差的函数如在功能SYM2(),主要思想所示开始从sym2(a1,a2)得到结果可以分为两个步骤:(1)。对于数组a1 []中的每个元素,如果a1 [j]不在数组a2 [] 中,则a1 [j]不在结果数组sym []中,则将a1 [j]推送到结果数组。 (!isin(a1 [j],syms)可以在a1 []中防止重复编号,例如sym2([1,1],[3])可以返回[1,3]而不是[1,1, 3]。在完成a1-a2之后,如果a2 [1]不在数组a1 []和a2 [l]中,则对数组a2 []中的每个元素以相同的方式执行第二步a2-a1 ]不在结果数组syms []中,则将a2 [l]推送到结果数组。

function sym()获取数组的列表,首先,我们可以将所有数组从参数保存到例如,如果arg包含[a1,a2,a3] arg.reduce(function(a,b){return sym2(arg [array1,array2,array3])和使用Array.reduce()函数。 (a,b)});执行如下:

  1. syms2(A1,A2)

  2. syms2(syms2(A1,A2),A3)

所有代码:

function isin(num,arra) 
{ 
    for (var i=0; i<arra.length; i++) 
     if (num == arra[i]){return true;} 
    return false; 
} 

function sym2(a1,a2) 
{ 
    var j,l; 
    var syms = []; 
    for (j=0; j<a1.length; j++){ 
     if(!isin(a1[j], a2)&&!isin(a1[j],syms)) 
      syms.push(a1[j]); 
     } 
    for (l=0; l<a2.length; l++){ 
     if(!isin(a2[l], a1)&&!isin(a2[l],syms)) 
      syms.push(a2[l]); 
     }  
    return syms; 
} 
function sym(){ 
    var arg=[]; 
    for(var o = 0; o<arguments.length;o++) 
     arg.push(arguments[o]); 
    return arg.reduce(function(a,b){ 
     return sym2(a,b); 
    }); 
} 
+0

请提供一些解释,除了代码。 – Jan