Javascript:将include方法传递给过滤器数组

3

通过向filter方法传递自定义函数,可以在Javascript中过滤数组:

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const filteredArray = bigArray.filter(item => item < 5);

将函数作为“参考”传递也是可能的:

function largerThanFive(item) {
  return item => item < 5;
}

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const filteredArray = bigArray.filter(largerThanFive);

我尝试使用下面的方法通过交集运算符(intersect)来对两个数组进行交集操作:

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const smallArray = [0, 1, 2];
const filteredArray = bigArray.filter(smallArray.includes);

但是我收到了错误提示: TypeError: 无法将未定义或空值转换为对象 我不明白为什么会出现这个错误。有人可以详细解释一下吗?

正如尼娜的回答所示,主要问题在于函数不是(仅仅是)对象方法。当您传递一个对象方法的引用时,除非该函数绑定到该对象(通过bind或箭头函数绑定等方式),否则您已经失去了对this的引用。 - Scott Sauyet
1
这个回答解决了你的问题吗?使用高阶函数的字符串方法 - ASDFGerte
2个回答

9
通过使用原型函数,您会失去对对象的引用。在这种情况下,您需要使用Function#bind将对象绑定。

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const smallArray = [0, 1, 2];
const filteredArray = bigArray.filter(Array.prototype.includes.bind(smallArray));

console.log(filteredArray);

或者使用 Array#filterthisArg 参数。

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const smallArray = [2, 1, 0];
const filteredArray = bigArray.filter(Array.prototype.includes, smallArray);

console.log(filteredArray); // 2 is missing

但是上述两种方法都不起作用,因为Array#includes使用了第二个参数fromIndex,它从调用函数中作为index传递,并省略了要检查的索引较小的值。
因此,您需要一个函数,它支持与所提供方法的API相同的函数签名,或者比回调函数使用的函数更小。
例如,一种可行的方法是将Set用作thisArg,并结合使用Set#has作为回调。该方法仅使用一个参数,非常适合。

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const smallArray = [2, 1, 0];
const filteredArray = bigArray.filter(Set.prototype.has, new Set(smallArray));

console.log(filteredArray);


或者当然可以直接传递一个lambda表达式:bigArray .filter (x => smallArray .includes (x)) - Scott Sauyet
我刚刚学到.filter作为它的第二个参数需要一个this参数。谢谢,非常有帮助。 - TKoL
1
这里省略了重复目标中解释的第二个问题 - filter 将当前索引作为第二个参数传递,而 includes 接受一个可选的第二个参数 fromIndex - ASDFGerte
Nina,感谢你的回答。我同意@ASDFGerte的观点-你的回答没有解决另一个bug。我还注意到,如果你能解释一下“对象”在你说“你正在失去对对象的引用”时是什么意思,那会更有信息量。 - Bashu Naimi-Roy
1
@BashuNaimi-Roy,请查看修改。 - Nina Scholz
非常感谢你花费时间,尼娜,翻译得很好。 - Bashu Naimi-Roy

3
错误TypeError: Cannot convert undefined or null to object是因为您调用一个期望参数为Object的函数,但是传入了undefined或null。
您可以获取筛选器(filter)内的每个项目, 然后检查smallArray是否拥有该项,例如:
smallArray.includes(item);

以下是代码片段:

const bigArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const smallArray = [0, 1, 2];
const filteredArray = bigArray.filter(item => {
  return smallArray.includes(item);
});

console.log(filteredArray);


这是绝对正确的,但并没有回答问题: 我不明白为什么。有人能详细解释一下吗?``` - Bashu Naimi-Roy
@BashuNaimi-Roy,更新了错误原因的说明。 - Maniraj Murugan
谢谢您的更新。您能否澄清一下哪个函数期望将对象作为其参数,并解释为什么在这种情况下它接收到了未定义/空值? - Bashu Naimi-Roy

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