简体   繁体   English

查找数组的交集不起作用?

[英]Finding intersection of arrays not working?

I have a two dimensional array with an arbitrary number of elements in each dimension, so it's an [m][n] array, but the second dimension length ( n ) is variable. 我有一个二维数组,每个维度中都有任意数量的元素,所以它是[m] [n]数组,但是第二维长度( n )是可变的。

Each element in the second dimension contains a number and there will only be one number that exists in all of the dimensions. 第二维中的每个元素都包含一个数字,并且所有维中都将只有一个数字。

So, for example, the array might be: 因此,例如,数组可能是:

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

Keep in mind that m can be > 2. 请记住, m可以> 2。

Here's my code: 这是我的代码:

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

The output is this: 输出是这样的:

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/ JSFIDDLE: http : //jsfiddle.net/hDL8K/

As you can see, it almost works, but it fails to remove two of the values. 如您所见,它几乎可以工作,但是无法删除其中两个值。

I think this might have something to do with the index in the foreach loop increasing with each loop and the array size decreasing because elements are being removed, but I'm not sure. 我认为这可能与foreach循环中的index随每个循环的增加以及数组大小的减小(因为要删除的元素)有关,但是我不确定。

Why is this not working, and how can I fix it? 为什么这不起作用,我该如何解决?

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

Simple JavaScript version: 简单的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);

Output 输出量

[ 126 ]

If the arrays are too big, then its better to convert them to Objects and then find the intersection. 如果数组太大,最好将它们转换为对象,然后找到交集。 Because item lookup in Objects will be much faster for larger arrays. 因为在大型数组中,对象中的项目查找会快得多。

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

I expect your problem stems from the fact that your array lengths are being modified as you remove items from the array. 我希望您的问题源于以下事实:从阵列中删除项目时,阵列长度正在被修改。 Rather than manipulating the array directly, you could have a function construct a new array with your result. 可以直接使用结果构造一个新数组,而不是直接操作该数组。 I find in general this approach can help reduce bugs in code. 我发现这种方法通常可以帮助减少代码中的错误。 From your existing code it could be something like this: 从您现有的代码中可能是这样的:

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 . 这里的例子 Though that does produce a multidimensional array containing intersections - you may just want the first element of it. 尽管这确实会产生包含相交的多维数组-您可能只需要它的第一个元素。

Don't know exactly where the problem in your solution is, but.. 不知道您的解决方案到底在哪里,但是..
Here you have a solution 在这里你有一个解决方案

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

EDIT : If you want to find the intersection without modifing the original array, just change the last lines of code by: 编辑 :如果要查找交集而不修改原始数组,只需通过以下方式更改代码的最后几行:

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

Output: [126] 输出: [126]

Cheers, from La Paz, Bolivia 来自玻利维亚拉巴斯的欢呼声

I updated your method a little bit: 我对您的方法做了一点更新:

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
        }

    });
}

Try it now: http://jsfiddle.net/SabdielRivera/hDL8K/2/ 立即尝试: http : //jsfiddle.net/SabdielRivera/hDL8K/2/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM