如何从一个数组中过滤掉另一个数组的所有元素

335


我想了解从另一个数组中过滤掉所有元素的最佳方法。我尝试使用筛选函数,但是我不知道如何给它要移除的值。类似于:

var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(myCallback);
// filteredArray should now be [1,3]


function myCallBack(){
    return element ! filteredArray; 
    //which clearly can't work since we don't have the reference <,< 
}

如果过滤函数无法发挥作用,您将如何实现此操作?
编辑:我检查了可能的重复问题,并且对于那些容易理解JavaScript的人可能会有用。被选为好答案的答案使事情变得容易。


13
将另一个数组传递给过滤器回调函数并使用 return arrTwo.indexOf(e) === -1;代码: var filteredArr = firstArr.filter(el => secondArr.indexOf(el) === -1); (将第一个数组中不在第二个数组中的元素筛选出来的代码,可以使用上述语句实现) - Tushar
1
可能是重复的问题:.filter()使用另一个数组元素过滤数组 - Dawid Rutkowski
这两个数组都是有序的吗? - Nina Scholz
数组并非有序,而且第二个数组的元素数量是随机的。 - Robdll
24个回答

1

Jack Giffin的解决方案非常好,但对于数字大于2^32的数组无效。下面是一个重构的、快速的版本,基于Jack的解决方案过滤一个数组,但它适用于64位数组。

const Math_clz32 = Math.clz32 || ((log, LN2) => x => 31 - log(x >>> 0) / LN2 | 0)(Math.log, Math.LN2);

const filterArrayByAnotherArray = (searchArray, filterArray) => {

    searchArray.sort((a,b) => a > b);
    filterArray.sort((a,b) => a > b);

    let searchArrayLen = searchArray.length, filterArrayLen = filterArray.length;
    let progressiveLinearComplexity = ((searchArrayLen<<1) + filterArrayLen)>>>0
    let binarySearchComplexity = (searchArrayLen * (32-Math_clz32(filterArrayLen-1)))>>>0;

    let i = 0;

    if (progressiveLinearComplexity < binarySearchComplexity) {
      return searchArray.filter(currentValue => {
        while (filterArray[i] < currentValue) i=i+1|0;
        return filterArray[i] !== currentValue;
      });
    }
    else return searchArray.filter(e => binarySearch(filterArray, e) === null);
}

const binarySearch = (sortedArray, elToFind) => {
  let lowIndex = 0;
  let highIndex = sortedArray.length - 1;
  while (lowIndex <= highIndex) {
    let midIndex = Math.floor((lowIndex + highIndex) / 2);
    if (sortedArray[midIndex] == elToFind) return midIndex; 
    else if (sortedArray[midIndex] < elToFind) lowIndex = midIndex + 1;
    else highIndex = midIndex - 1;
  } return null;
}

0

我只是想给你提供一个额外的解决方案...

const arr1 = [1,2,3,4];
const arr2 = [2,4];
const container = arr2.reduce((res,item) => {
 res[item] = true;
 return res;
}, {});
const result = arr1.filter(item => !container[item]);

关于上述代码的时间复杂度:O(n)。并且,我们需要更多的空间(空间复杂度O(n))=> 折衷... :))

0
如果你想用一些匹配属性来过滤具有不同结构的数组,你应该这样做。
let filteredArray = [];

array1.map(array1Item => {
array2.map(array2Item => {
  if (array1.property1 === array2.property2) {
    filteredArray.push(array1Item);
  }
});

这应该会让你的生活变得更轻松!


-2

这个答案只使用了一个数组。 - giraffe.guru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接