簡體   English   中英

查找數組的交集不起作用?

[英]Finding intersection of arrays not working?

我有一個二維數組,每個維度中都有任意數量的元素,所以它是[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隨每個循環的增加以及數組大小的減小(因為要刪除的元素)有關,但是我不確定。

為什么這不起作用,我該如何解決?

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);

簡單的JavaScript版本:

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);

我希望您的問題源於以下事實:從陣列中刪除項目時,陣列長度正在被修改。 可以直接使用結果構造一個新數組,而不是直接操作該數組。 我發現這種方法通常可以幫助減少代碼中的錯誤。 從您現有的代碼中可能是這樣的:

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;
}

這里的例子 盡管這確實會產生包含相交的多維數組-您可能只需要它的第一個元素。

不知道您的解決方案到底在哪里,但是..
在這里你有一個解決方案

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);

編輯 :如果要查找交集而不修改原始數組,只需通過以下方式更改代碼的最后幾行:

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

輸出: [126]

來自玻利維亞拉巴斯的歡呼聲

我對您的方法做了一點更新:

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/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM