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

< p > < br > 我想了解从另一个数组的所有元素中筛选一个数组的最佳方法。我尝试了过滤功能,但它不来我如何给它的值,我想删除。
类似于:

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的人有用。如果答案勾选“好”,事情就简单多了。

554367 次浏览

filter函数的最佳描述是https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Array/filter

你应该简单地条件函数:

function conditionFun(element, index, array) {
return element >= 10;
}
filtered = [12, 5, 8, 130, 44].filter(conditionFun);

在变量值被赋值之前,您不能访问它

你可以设置过滤器函数来遍历“过滤器数组”。

var arr = [1, 2, 3 ,4 ,5, 6, 7];
var filter = [4, 5, 6];


var filtered = arr.filter(
function(val) {
for (var i = 0; i < filter.length; i++) {
if (val == filter[i]) {
return false;
}
}
return true;
}
);
var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(myCallBack);


function myCallBack(el){
return anotherOne.indexOf(el) < 0;
}

在回调中,检查array的每个值是否在anotherOne

https://jsfiddle.net/0tsyc1sx/

如果使用lodash.js,则使用_.difference

filteredArray = _.difference(array, anotherOne);

Demo

如果你有一个对象数组:

var array = [{id :1, name :"test1"},{id :2, name :"test2"},{id :3, name :"test3"},{id :4, name :"test4"}];


var anotherOne = [{id :2, name :"test2"}, {id :4, name :"test4"}];


var filteredArray  = array.filter(function(array_el){
return anotherOne.filter(function(anotherOne_el){
return anotherOne_el.id == array_el.id;
}).length == 0
});

演示对象数组 . 使用lodash演示对象的diff数组

您可以使用过滤器,然后为过滤器函数使用过滤数组的约简,当它找到匹配时检查并返回true,然后在返回(!)时反转。filter函数对数组中的每个元素调用一次。在你的文章中,你没有对函数中的任何元素进行比较。

.
var a1 = [1, 2, 3, 4],
a2 = [2, 3];


var filtered = a1.filter(function(x) {
return !a2.reduce(function(y, z) {
return x == y || x == z || y == true;
})
});


document.write(filtered);

可以使用filter()函数的this参数来避免将过滤器数组存储在全局变量中。

var filtered = [1, 2, 3, 4].filter(
function(e) {
return this.indexOf(e) < 0;
},
[2, 4]
);
console.log(filtered);

.
var arr1= [1,2,3,4];
var arr2=[2,4]


function fil(value){
return value !=arr2[0] &&  value != arr2[1]
}


document.getElementById("p").innerHTML= arr1.filter(fil)
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p id="p"></p>

.
function arr(arr1,arr2){
  

function filt(value){
return arr2.indexOf(value) === -1;
}
  

return arr1.filter(filt)
}


document.getElementById("p").innerHTML = arr([1,2,3,4],[2,4])
<p id="p"></p>

我会这样做;

var arr1 = [1,2,3,4],
arr2 = [2,4],
res = arr1.filter(item => !arr2.includes(item));
console.log(res);

来自另一个包含对象属性的数组的更灵活的过滤数组

function filterFn(array, diffArray, prop, propDiff) {
diffArray = !propDiff ? diffArray : diffArray.map(d => d[propDiff])
this.fn = f => diffArray.indexOf(f) === -1
if (prop) {
return array.map(r => r[prop]).filter(this.fn)
} else {
return array.filter(this.fn)
}
}


//You can use it like this;


var arr = [];


for (var i = 0; i < 10; i++) {
var obj = {}
obj.index = i
obj.value = Math.pow(2, i)
arr.push(obj)
}


var arr2 = [1, 2, 3, 4, 5]


var sec = [{t:2}, {t:99}, {t:256}, {t:4096}]


var log = console.log.bind(console)


var filtered = filterFn(arr, sec, 'value', 't')


var filtered2 = filterFn(arr2, sec, null, 't')


log(filtered, filtered2)

你可以写一个泛型的filterByIndex()函数,并在TS中使用类型推断来省去回调函数的麻烦:

假设你有一个数组[1,2,3,4],你想用[2,4]数组中指定的下标来过滤()。

var filtered = [1,2,3,4,].filter(byIndex(element => element, [2,4]))

byIndex函数需要元素函数和数组,如下所示:

byIndex = (getter: (e:number) => number, arr: number[]) => (x: number) => {
var i = getter(x);
return arr.indexOf(i);
}

结果就是这样

filtered = [1,3]

下面的例子使用new Set()创建一个只有唯一元素的过滤数组:

数组的基本数据类型:字符串,数字,布尔,空,未定义,符号:

const a = [1, 2, 3, 4];
const b = [3, 4, 5];
const c = Array.from(new Set(a.concat(b)));

以对象为项的数组:

const a = [{id:1}, {id: 2}, {id: 3}, {id: 4}];
const b = [{id: 3}, {id: 4}, {id: 5}];
const stringifyObject = o => JSON.stringify(o);
const parseString = s => JSON.parse(s);
const c = Array.from(new Set(a.concat(b).map(stringifyObject)), parseString);

上述所有的解决方案都“有效”,但在性能上都不是最优的,并且都以相同的方式处理问题,即在每个点上使用Array.prototype.indexOfArray.prototype.includes线性搜索所有条目。一个更快的解决方案(在大多数情况下甚至比二进制搜索快得多)是对数组进行排序,并在执行过程中跳过,如下所示。然而,一个缺点是,这要求数组中的所有条目都是数字或字符串。然而,在一些罕见的情况下,二分搜索可能比渐进线性搜索更快。这些情况产生于这样一个事实:我的渐进式线性搜索的复杂度为O (2 n <子> 1子> < / 2 + n <子> < /子>)(在更快的C/ c++版本中只有O (n <子> 1子> < / 2 + n <子> < /子>))(其中n <子> 1子> < /是被搜索的数组,n <子> 2子> < /是过滤器数组),而二进制搜索的复杂度为O (n <子> 1 < /子>装天花板(日志<子> 2 < /子> n <子> 2 < / sub >)) (ceil =四舍五入—到装天花板ing),最后,indexOf搜索的复杂度在O (n <子> 1 < / sub >)O (n <子> 1 < /子> n <子> 2 < / sub >)之间具有高度可变的复杂度,平均为Array.prototype.includes0。因此,平均而言,只有在Array.prototype.includes1等于Array.prototype.includes2、Array.prototype.includes3或Array.prototype.includes4的情况下,indexOf才是最快的。然而,这仍然不是现代硬件的完美代表。IndexOf在大多数现代浏览器中都是完全优化的,这使得它非常受制于Array.prototype.includes5的规则。因此,如果我们对indexOf进行与渐进线性和二进制搜索相同的假设——数组是预先排序的——那么,根据链接中列出的统计数据,我们可以预期indexOf的速度大约提高6倍,将其复杂性转移到Array.prototype.includes6和O (n <子> 1 < /子> n <子> 2 < / sub >)之间,平均为Array.prototype.includes8。最后,请注意,下面的解决方案永远不能用于对象,因为JavaScript中的对象不能与JavaScript中的指针进行比较。

function sortAnyArray(a,b) { return a>b ? 1 : (a===b ? 0 : -1); }
function sortIntArray(a,b) { return (a|0) - (b|0) |0; }
function fastFilter(array, handle) {
var out=[], value=0;
for (var i=0,  len=array.length|0; i < len; i=i+1|0)
if (handle(value = array[i]))
out.push( value );
return out;
}


const Math_clz32 = Math.clz32 || (function(log, LN2){
return function(x) {
return 31 - log(x >>> 0) / LN2 | 0; // the "| 0" acts like math.floor
};
})(Math.log, Math.LN2);


/* USAGE:
filterArrayByAnotherArray(
[1,3,5],
[2,3,4]
) yields [1, 5], and it can work with strings too
*/
function filterArrayByAnotherArray(searchArray, filterArray) {
if (
// NOTE: This does not check the whole array. But, if you know
//        that there are only strings or numbers (not a mix of
//        both) in the array, then this is a safe assumption.
// Always use `==` with `typeof` because browsers can optimize
//  the `==` into `===` (ONLY IN THIS CIRCUMSTANCE)
typeof searchArray[0] == "number" &&
typeof filterArray[0] == "number" &&
(searchArray[0]|0) === searchArray[0] &&
(filterArray[0]|0) === filterArray[0]
) {filterArray
// if all entries in both arrays are integers
searchArray.sort(sortIntArray);
filterArray.sort(sortIntArray);
} else {
searchArray.sort(sortAnyArray);
filterArray.sort(sortAnyArray);
}
var searchArrayLen = searchArray.length, filterArrayLen = filterArray.length;
var progressiveLinearComplexity = ((searchArrayLen<<1) + filterArrayLen)>>>0
var binarySearchComplexity= (searchArrayLen * (32-Math_clz32(filterArrayLen-1)))>>>0;
// After computing the complexity, we can predict which algorithm will be the fastest
var i = 0;
if (progressiveLinearComplexity < binarySearchComplexity) {
// Progressive Linear Search
return fastFilter(searchArray, function(currentValue){
while (filterArray[i] < currentValue) i=i+1|0;
// +undefined = NaN, which is always false for <, avoiding an infinite loop
return filterArray[i] !== currentValue;
});
} else {
// Binary Search
return fastFilter(
searchArray,
fastestBinarySearch(filterArray)
);
}
}


// see https://stackoverflow.com/a/44981570/5601591 for implementation
//  details about this binary search algorithm


function fastestBinarySearch(array){
var initLen = (array.length|0) - 1 |0;
  

const compGoto = Math_clz32(initLen) & 31;
return function(sValue) {
var len = initLen |0;
switch (compGoto) {
case 0:
if (len & 0x80000000) {
const nCB = len & 0x80000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 1:
if (len & 0x40000000) {
const nCB = len & 0xc0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 2:
if (len & 0x20000000) {
const nCB = len & 0xe0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 3:
if (len & 0x10000000) {
const nCB = len & 0xf0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 4:
if (len & 0x8000000) {
const nCB = len & 0xf8000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 5:
if (len & 0x4000000) {
const nCB = len & 0xfc000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 6:
if (len & 0x2000000) {
const nCB = len & 0xfe000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 7:
if (len & 0x1000000) {
const nCB = len & 0xff000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 8:
if (len & 0x800000) {
const nCB = len & 0xff800000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 9:
if (len & 0x400000) {
const nCB = len & 0xffc00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 10:
if (len & 0x200000) {
const nCB = len & 0xffe00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 11:
if (len & 0x100000) {
const nCB = len & 0xfff00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 12:
if (len & 0x80000) {
const nCB = len & 0xfff80000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 13:
if (len & 0x40000) {
const nCB = len & 0xfffc0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 14:
if (len & 0x20000) {
const nCB = len & 0xfffe0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 15:
if (len & 0x10000) {
const nCB = len & 0xffff0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 16:
if (len & 0x8000) {
const nCB = len & 0xffff8000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 17:
if (len & 0x4000) {
const nCB = len & 0xffffc000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 18:
if (len & 0x2000) {
const nCB = len & 0xffffe000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 19:
if (len & 0x1000) {
const nCB = len & 0xfffff000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 20:
if (len & 0x800) {
const nCB = len & 0xfffff800;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 21:
if (len & 0x400) {
const nCB = len & 0xfffffc00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 22:
if (len & 0x200) {
const nCB = len & 0xfffffe00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 23:
if (len & 0x100) {
const nCB = len & 0xffffff00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 24:
if (len & 0x80) {
const nCB = len & 0xffffff80;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 25:
if (len & 0x40) {
const nCB = len & 0xffffffc0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 26:
if (len & 0x20) {
const nCB = len & 0xffffffe0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 27:
if (len & 0x10) {
const nCB = len & 0xfffffff0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 28:
if (len & 0x8) {
const nCB = len & 0xfffffff8;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 29:
if (len & 0x4) {
const nCB = len & 0xfffffffc;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 30:
if (len & 0x2) {
const nCB = len & 0xfffffffe;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 31:
if (len & 0x1) {
const nCB = len & 0xffffffff;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
}
// MODIFICATION: Instead of returning the index, this binary search
//                instead returns whether something was found or not.
if (array[len|0] !== sValue) {
return true; // preserve the value at this index
} else {
return false; // eliminate the value at this index
}
};
}

请参阅我的另一篇文章here关于所使用的二进制搜索算法的更多细节

如果您对文件大小很挑剔(我尊重这一点),那么您可以牺牲一点性能,以大大减小文件大小并提高可维护性。

function sortAnyArray(a,b) { return a>b ? 1 : (a===b ? 0 : -1); }
function sortIntArray(a,b) { return (a|0) - (b|0) |0; }
function fastFilter(array, handle) {
var out=[], value=0;
for (var i=0,  len=array.length|0; i < len; i=i+1|0)
if (handle(value = array[i]))
out.push( value );
return out;
}


/* USAGE:
filterArrayByAnotherArray(
[1,3,5],
[2,3,4]
) yields [1, 5], and it can work with strings too
*/
function filterArrayByAnotherArray(searchArray, filterArray) {
if (
// NOTE: This does not check the whole array. But, if you know
//        that there are only strings or numbers (not a mix of
//        both) in the array, then this is a safe assumption.
typeof searchArray[0] == "number" &&
typeof filterArray[0] == "number" &&
(searchArray[0]|0) === searchArray[0] &&
(filterArray[0]|0) === filterArray[0]
) {
// if all entries in both arrays are integers
searchArray.sort(sortIntArray);
filterArray.sort(sortIntArray);
} else {
searchArray.sort(sortAnyArray);
filterArray.sort(sortAnyArray);
}
// Progressive Linear Search
var i = 0;
return fastFilter(searchArray, function(currentValue){
while (filterArray[i] < currentValue) i=i+1|0;
// +undefined = NaN, which is always false for <, avoiding an infinite loop
return filterArray[i] !== currentValue;
});
}

为了证明速度上的差异,让我们检查一些jsperf。对于筛选16个元素的数组,二进制搜索大约比indexOf快17%,而filterArrayByAnotherArray大约比indexOf快93%。对于过滤256个元素的数组,二进制搜索大约比indexOf快291%,而filterArrayByAnotherArray大约比indexOf快353%。对于筛选4096个元素的数组,二进制搜索大约比indexOf快2655%,而filterArrayByAnotherArray大约比indexOf快4627%。

反向滤波(如与门)

上一节提供了获取数组A和数组B的代码,并删除A中存在于B中的所有元素:

filterArrayByAnotherArray(
[1,3,5],
[2,3,4]
);
// yields [1, 5]

下一节将提供反向过滤的代码,其中我们从A中删除B中不存在的所有元素。这个过程在功能上相当于只保留A和B的公共元素,如and门:

reverseFilterArrayByAnotherArray(
[1,3,5],
[2,3,4]
);
// yields [3]

下面是反向过滤的代码:

function sortAnyArray(a,b) { return a>b ? 1 : (a===b ? 0 : -1); }
function sortIntArray(a,b) { return (a|0) - (b|0) |0; }
function fastFilter(array, handle) {
var out=[], value=0;
for (var i=0,  len=array.length|0; i < len; i=i+1|0)
if (handle(value = array[i]))
out.push( value );
return out;
}


const Math_clz32 = Math.clz32 || (function(log, LN2){
return function(x) {
return 31 - log(x >>> 0) / LN2 | 0; // the "| 0" acts like math.floor
};
})(Math.log, Math.LN2);


/* USAGE:
reverseFilterArrayByAnotherArray(
[1,3,5],
[2,3,4]
) yields [3], and it can work with strings too
*/
function reverseFilterArrayByAnotherArray(searchArray, filterArray) {
if (
// NOTE: This does not check the whole array. But, if you know
//        that there are only strings or numbers (not a mix of
//        both) in the array, then this is a safe assumption.
// Always use `==` with `typeof` because browsers can optimize
//  the `==` into `===` (ONLY IN THIS CIRCUMSTANCE)
typeof searchArray[0] == "number" &&
typeof filterArray[0] == "number" &&
(searchArray[0]|0) === searchArray[0] &&
(filterArray[0]|0) === filterArray[0]
) {
// if all entries in both arrays are integers
searchArray.sort(sortIntArray);
filterArray.sort(sortIntArray);
} else {
searchArray.sort(sortAnyArray);
filterArray.sort(sortAnyArray);
}
var searchArrayLen = searchArray.length, filterArrayLen = filterArray.length;
var progressiveLinearComplexity = ((searchArrayLen<<1) + filterArrayLen)>>>0
var binarySearchComplexity= (searchArrayLen * (32-Math_clz32(filterArrayLen-1)))>>>0;
// After computing the complexity, we can predict which algorithm will be the fastest
var i = 0;
if (progressiveLinearComplexity < binarySearchComplexity) {
// Progressive Linear Search
return fastFilter(searchArray, function(currentValue){
while (filterArray[i] < currentValue) i=i+1|0;
// +undefined = NaN, which is always false for <, avoiding an infinite loop
// For reverse filterning, I changed !== to ===
return filterArray[i] === currentValue;
});
} else {
// Binary Search
return fastFilter(
searchArray,
inverseFastestBinarySearch(filterArray)
);
}
}


// see https://stackoverflow.com/a/44981570/5601591 for implementation
//  details about this binary search algorithim


function inverseFastestBinarySearch(array){
var initLen = (array.length|0) - 1 |0;
  

const compGoto = Math_clz32(initLen) & 31;
return function(sValue) {
var len = initLen |0;
switch (compGoto) {
case 0:
if (len & 0x80000000) {
const nCB = len & 0x80000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 1:
if (len & 0x40000000) {
const nCB = len & 0xc0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 2:
if (len & 0x20000000) {
const nCB = len & 0xe0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 3:
if (len & 0x10000000) {
const nCB = len & 0xf0000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 4:
if (len & 0x8000000) {
const nCB = len & 0xf8000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 5:
if (len & 0x4000000) {
const nCB = len & 0xfc000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 6:
if (len & 0x2000000) {
const nCB = len & 0xfe000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 7:
if (len & 0x1000000) {
const nCB = len & 0xff000000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 8:
if (len & 0x800000) {
const nCB = len & 0xff800000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 9:
if (len & 0x400000) {
const nCB = len & 0xffc00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 10:
if (len & 0x200000) {
const nCB = len & 0xffe00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 11:
if (len & 0x100000) {
const nCB = len & 0xfff00000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 12:
if (len & 0x80000) {
const nCB = len & 0xfff80000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 13:
if (len & 0x40000) {
const nCB = len & 0xfffc0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 14:
if (len & 0x20000) {
const nCB = len & 0xfffe0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 15:
if (len & 0x10000) {
const nCB = len & 0xffff0000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 16:
if (len & 0x8000) {
const nCB = len & 0xffff8000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 17:
if (len & 0x4000) {
const nCB = len & 0xffffc000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 18:
if (len & 0x2000) {
const nCB = len & 0xffffe000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 19:
if (len & 0x1000) {
const nCB = len & 0xfffff000;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 20:
if (len & 0x800) {
const nCB = len & 0xfffff800;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 21:
if (len & 0x400) {
const nCB = len & 0xfffffc00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 22:
if (len & 0x200) {
const nCB = len & 0xfffffe00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 23:
if (len & 0x100) {
const nCB = len & 0xffffff00;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 24:
if (len & 0x80) {
const nCB = len & 0xffffff80;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 25:
if (len & 0x40) {
const nCB = len & 0xffffffc0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 26:
if (len & 0x20) {
const nCB = len & 0xffffffe0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 27:
if (len & 0x10) {
const nCB = len & 0xfffffff0;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 28:
if (len & 0x8) {
const nCB = len & 0xfffffff8;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 29:
if (len & 0x4) {
const nCB = len & 0xfffffffc;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 30:
if (len & 0x2) {
const nCB = len & 0xfffffffe;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
case 31:
if (len & 0x1) {
const nCB = len & 0xffffffff;
len ^= (len ^ (nCB-1)) & ((array[nCB] <= sValue |0) - 1 >>>0);
}
}
// MODIFICATION: Instead of returning the index, this binary search
//                instead returns whether something was found or not.
// For reverse filterning, I swapped true with false and vice-versa
if (array[len|0] !== sValue) {
return false; // preserve the value at this index
} else {
return true; // eliminate the value at this index
}
};
}

有关反向过滤代码的较慢的较小版本,请参见下面。

function sortAnyArray(a,b) { return a>b ? 1 : (a===b ? 0 : -1); }
function sortIntArray(a,b) { return (a|0) - (b|0) |0; }
function fastFilter(array, handle) {
var out=[], value=0;
for (var i=0,  len=array.length|0; i < len; i=i+1|0)
if (handle(value = array[i]))
out.push( value );
return out;
}


/* USAGE:
reverseFilterArrayByAnotherArray(
[1,3,5],
[2,3,4]
) yields [3], and it can work with strings too
*/
function reverseFilterArrayByAnotherArray(searchArray, filterArray) {
if (
// NOTE: This does not check the whole array. But, if you know
//        that there are only strings or numbers (not a mix of
//        both) in the array, then this is a safe assumption.
typeof searchArray[0] == "number" &&
typeof filterArray[0] == "number" &&
(searchArray[0]|0) === searchArray[0] &&
(filterArray[0]|0) === filterArray[0]
) {
// if all entries in both arrays are integers
searchArray.sort(sortIntArray);
filterArray.sort(sortIntArray);
} else {
searchArray.sort(sortAnyArray);
filterArray.sort(sortAnyArray);
}
// Progressive Linear Search
var i = 0;
return fastFilter(searchArray, function(currentValue){
while (filterArray[i] < currentValue) i=i+1|0;
// +undefined = NaN, which is always false for <, avoiding an infinite loop
// For reverse filter, I changed !== to ===
return filterArray[i] === currentValue;
});
}

        /* Here's an example that uses (some) ES6 Javascript semantics to filter an object array by another object array. */


// x = full dataset
// y = filter dataset
let x = [
{"val": 1, "text": "a"},
{"val": 2, "text": "b"},
{"val": 3, "text": "c"},
{"val": 4, "text": "d"},
{"val": 5, "text": "e"}
],
y = [
{"val": 1, "text": "a"},
{"val": 4, "text": "d"}
];


// Use map to get a simple array of "val" values. Ex: [1,4]
let yFilter = y.map(itemY => { return itemY.val; });


// Use filter and "not" includes to filter the full dataset by the filter dataset's val.
let filteredX = x.filter(itemX => !yFilter.includes(itemX.val));


// Print the result.
console.log(filteredX);

OA也可以在ES6中实现,如下所示

ES6:

 const filtered = [1, 2, 3, 4].filter(e => {
return this.indexOf(e) < 0;
},[2, 4]);

你的问题有很多答案,但我没有看到任何人使用lambda表达式:

var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(x => anotherOne.indexOf(x) < 0);

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

下面的代码是根据另一个数组过滤一个数组的最简单方法。两个数组都可以在其中包含对象而不是值。

let array1 = [1, 3, 47, 1, 6, 7];
let array2 = [3, 6];
let filteredArray1 = array1.filter(el => array2.includes(el));
console.log(filteredArray1); 

输出:[3, 6]

下面是一个例子

let firstArray=[1,2,3,4,5];
let secondArray=[2,3];
let filteredArray = firstArray.filter((a) => secondArray.indexOf(a)<0);
console.log(filteredArray); //above line gives [1,4,5]

如果你需要比较一个对象数组,这在所有情况下都适用:

let arr = [{ id: 1, title: "title1" },{ id: 2, title: "title2" }]
let brr = [{ id: 2, title: "title2" },{ id: 3, title: "title3" }]


const res = arr.filter(f => brr.some(item => item.id === f.id));
console.log(res);

使用对象筛选结果

[{id:1},{id:2},{id:3},{id:4}].filter(v=>!([{id:2},{id:4}].some(e=>e.id === v.id)))

enter image description here

下面是当数组中的项是对象时的操作方法。

其思想是使用map函数在内部数组中查找仅包含键的数组

然后检查这些键的数组是否包含外层数组中的特定元素键。

const existsInBothArrays = array1.filter((element1) =>
array2.map((element2) => element2._searchKey).includes(element1._searchKey),
);

我只是想给你一个额外的解决方案…

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)) =>权衡……:)) < / p >

PHP 4+有一个内置函数来实现这一点。

array_diff ()array_diff_assoc ()如果你还想在比较中考虑关联数组的键,或者array_diff_key ()如果你出于某种原因只想在比较中考虑键

$array1 = array("a" => "green", "red", "blue", "red");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2); // returns Array([1] => blue)

如果你想做相反的事情,函数array_intersect ()值得一看。

如果你想过滤一个具有一些匹配属性的不同结构的数组,你应该这样做。

let filteredArray = [];


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

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