React如何过滤不包含指定值的数组?问题排查
反转食谱食材筛选逻辑的问题
我有一个食谱数组,原本可以筛选出包含目标食材的条目,但想反转逻辑(筛选完全不包含目标食材的食谱)时,写出来的代码只会检查数组首个元素,达不到预期效果。
数据结构示例
[ { // 其他属性... ingredients: [ "面粉", "鸡蛋", "牛奶" // 更多食材字符串 ] // 其他属性... } ]
正常工作的正向筛选代码
这个方法可以正确筛选出包含目标食材的食谱:
const getData = (data, target) => { return data.filter((entry) => { return entry.ingredients.some((item) => { return item.toLowerCase().includes(target); }); }); };
尝试的错误反转写法
以下两种写法都无法正确筛选,只有当目标食材位于ingredients数组第一个索引时才会生效:
写法1:
const getData = (data, target) => { return data.filter((entry) => { return entry.ingredients.some((item) => { return !item.toLowerCase().includes(target); }); }); };
写法2:
const getData = (data, target) => { return data.filter((entry) => { return entry.ingredients.some((item) => { return item.toLowerCase().includes(target) === false; }); }); };
调用方式:
const newData = getData(oldData, "nut");
问题原因
some()方法的逻辑是:只要数组里有一个元素满足条件,就返回true。上面的错误写法中,只要食谱里有任意一个食材不包含目标,some()就会返回true,进而保留这个食谱——哪怕该食谱里其他食材包含目标,也会被错误筛选出来。这完全不是我们想要的“所有食材都不包含目标”的逻辑。
正确的反转写法
有两种等价的正确实现方式:
方式1:使用every()检查所有食材
every()会确保数组中所有元素都满足条件才返回true,正好符合我们的需求:
const getData = (data, target) => { return data.filter((entry) => { return entry.ingredients.every((item) => { return !item.toLowerCase().includes(target); }); }); };
方式2:对some()的结果取反
意思是“食谱里不存在任何包含目标的食材”,和方式1逻辑完全一致:
const getData = (data, target) => { return data.filter((entry) => { return !entry.ingredients.some((item) => { return item.toLowerCase().includes(target); }); }); };
内容的提问来源于stack exchange,提问作者Jack Duffy
相关产品推荐
相关产品推荐

