2014-01-05 3 views
1

나는 각 차원에 임의의 수의 요소가있는 2 차원 배열을 가지고 있으므로 [m] [n] 배열이지만 두 번째 차원 길이 (n)는 가변적입니다.배열의 교차점 찾기가 작동하지 않습니까?

두 번째 차원의 각 요소에는 숫자가 들어 있으며 모든 차원에 하나의 숫자 만 존재합니다.

따라서, 예를 들어, 배열이 될 수 있습니다 명심

[ 
    [ 
     126, 
     131, 
     138, 
     139, 
     140, 
     143 
    ], 
    [ 
     126, 
     201 
    ] 
] 

m이 될 수 있음을> 다음

2. 내 코드입니다 :

var theArray = [ 
    [126, 131, 138, 139, 140, 143], 
    [126, 201] 
]; 

for(var i = 0; i < theArray.length; i++) // loop through each array of numbers 
{ 
    $.each(theArray[i], function(index, value) // loop through all of the numbers in this array 
    { 
     var nextArray = (i+1<theArray.length?theArray[i+1]:theArray[0]); 
     if($.inArray(value, nextArray) == -1) // if this number is not in the next array 
     { 
      console.log("removing index: " + index + ", value: " + value); 
      theArray[i].splice(index, 1); // remove the number from the array 
     } 
    }); 
} 
console.log(theArray); 

이 출력은 이것이다 :

removing index: 1, value: 131 
removing index: 2, value: 139 
removing index: 3, value: 143 
removing index: 4, value: undefined 
removing index: 5, value: undefined 
removing index: 1, value: 201 

Array 
    [ 
     [ 
      126, 
      138, 
      140, 
     ], 
     [ 
      126 
     ] 
    ] 

JSFIDDLE : http://jsfiddle.net/hDL8K/

당신이 볼 수 있듯이, 그것은 거의 작동하지만이 값이 제거되지 않습니다.

요소가 제거되기 때문에 이것은 루프와 함께 증가하는 루프와 배열 크기가 줄어들면서 foreach 루프에있는 index과 관련이 있을지 모르지만 확실하지 않습니다.

왜 이것이 작동하지 않으며 어떻게 해결할 수 있습니까?

+1

당신이 밖으로 요소를 접합하기 때 때문에 작동하지 않습니다 종종를 반복하고있는 배열을 수정 나머지 요소에 대한 모든 색인이 아래로 이동합니다. – Barmar

+0

안녕하세요, 원래 배열을 수정하지 않는 솔루션을 추가했습니다. –

답변

2

Functional version with jQuery

var theArrays = [[126, 131, 138, 139, 140,143],[126, 201]],result = theArrays[0]; 

$.each(theArrays, function(index, currentArray) { 
    result = $.grep(result, function(currentElement) { 
     return currentArray.indexOf(currentElement) !== -1; 
    }); 
}); 

console.log(result); 

간단한 자바 스크립트 버전 : 배열은 다음의 더 나은 다음 객체로 변환하고, 너무 큰 경우

var theArrays = [[126, 131, 138, 139, 140,143],[126, 201]],result = theArrays[0]; 

for (var i = 1; i < theArrays.length; i += 1) { 
    for (var j = 0; j < result.length; j += 1) { 
     if (theArrays[i].indexOf(result[j]) === -1) { 
      result.splice(j, 1); 
      j -= 1; 
     } 
    } 
} 

console.log(result); 

출력

[ 126 ] 

교차로를 찾으십시오. 객체의 항목 조회는 큰 배열의 경우 훨씬 빠르기 때문에

var theObjects = []; 
for (var i = 0; i < theArrays.length; i += 1) { 
    var tempObject = {}; 
    for (var j = 0; j < theArrays[i].length; j += 1) { 
     tempObject[theArrays[i][j]] = true; 
    } 
    theObjects.push(tempObject); 
} 

var intersection = theObjects[0], result = []; 
for (var i = 1; i < theArrays.length; i += 1) { 
    for (var key in intersection) { 
     if (theObjects[i].hasOwnProperty(key) === false) { 
      delete intersection[key]; 
     } 
    } 
} 

for (var key in intersection) { 
    result.push(parseInt(key)); 
} 

console.log(result); 
+0

감사합니다. 이것은 정말 매끄 럽습니다! 그러나 코드가 원래 배열 (theArrays)을 수정한다는 것을 알았습니다. 그 주위에 어떤 방법이 있습니까? – Nate

+1

@Nate 환경에 ES5가 구현되어 있습니까? – thefourtheye

+0

그게 뭔지 잘 모르겠습니다. 그래서 :-) – Nate

1

문제점은 배열에서 항목을 제거 할 때 배열 길이가 변경된다는 사실에 기인합니다. 배열을 직접 조작하는 대신 결과를 사용하여 함수를 새 배열로 만들 수 있습니다. 일반적으로이 접근법은 코드의 버그를 줄이는 데 도움이 될 수 있습니다. 기존 코드에서 다음과 같이 될 수 있습니다.

function intersect(theArray){ 
    var result = []; 
    for(var i = 0; i < theArray.length; i++){ 
     var row = []; 
     $.each(theArray[i], function(index, value){ 
      var nextArray = (i+1 < theArray.length 
          ?theArray[i+1]:theArray[0]); 
      if($.inArray(value, nextArray) != -1) { 
       row.push(theArray[i][index]);  
      } 
     }); 
     result.push(row);   
    } 
    return result; 
} 

Example Here. 교차점을 포함하는 다차원 배열을 생성하기는하지만 그 요소의 첫 번째 요소 만 원할 수 있습니다.

1

솔루션의 문제가 정확히 어디인지는 모르지만 ..여기
당신은 솔루션을

var theArray = [ 
    [126, 131, 138, 139, 140, 143], 
    [126, 201] 
]; 

//Finds intersection of 2 arrays, returns new array 
function intersect_safe(a, b){ 
    var ai=0, bi=0; 
    var result = [];  
    while(ai < a.length && bi < b.length) { 
    if  (a[ai] < b[bi]){ ai++; } 
    else if (a[ai] > b[bi]){ bi++; } 
    else{ /* they're equal */  
     result.push(a[ai]); 
     ai++; 
     bi++; 
    } 
    } 
    return result; 
} 

for(var i = 0; i < theArray.length; i++){ // loop through each array of numbers  
    var nextIndex = (i+1) % theArray.length; 
    theArray[i] = intersect_safe(theArray[i], theArray[nextIndex]); 
} 
console.log(theArray); 

편집을 가지고 : 당신이이 원래의 배열을 modifing에없이 교차 를 찾으려면, 단지에서 코드의 마지막 줄을 변경 :

var intersection = theArray[0] || []; 
for(var i = 0; i < theArray.length; i++){ 
    intersection = intersect_safe(intersection, theArray[i]); 
} 
console.log(intersection); 

출력 :[126]

건배, La Paz, Boli에서

1

을 통해 나는 당신의 방법을 조금 업데이트 :

for(var i = 0; i < theArray.length; i++) // loop through each array of numbers 
{ 
    $.each(theArray[i], function(index, value) // loop through all of the numbers in this array 
    { 
     var nextArray = theArray[i + 1]; 

     if(nextArray !== undefined && $.inArray(value, nextArray) == 0) 
     { 
      console.log("removing index: " + index + ", value: " + value); 
      theArray[i].splice(index, 1); // remove the number from the array 
     } 

    }); 
} 

지금보십시오 : http://jsfiddle.net/SabdielRivera/hDL8K/2/

관련 문제