如何在JavaScript的filter()中使用forEach()过滤数组?
问题
我有一个对象数组,想要基于另一个数组对其进行过滤。当filters数组仅有一个值时,仅使用filter()就能正常筛选,但当filters包含多个值时,没有任何结果返回。因此我尝试在filter()中使用forEach()来筛选符合条件的值,请问问题出在哪里?
预期结果:
[ { "tags": [ "madewithout__gluten", "madewithout__nuts" ], "metafields": "Side" } ]
代码示例:
const data = [ { "tags": [ "madewithout__gluten", "madewithout__nuts" ], "metafields": "Side" }, { "tags": [ "madewithout__gluten" ], "metafields": "Side" }, { "tags": [ "madewithout__nuts" ], "metafields": "Side" } ] const filters = ['gluten', 'nuts'] const result = data.filter((v) => { filters.forEach((tag) => { if(!v.tags.includes(`madewithout__${tag}`)) return; }); }); console.log(result);
问题原因
你这段代码的核心问题有两个:
forEach里的return不会影响外层filter的返回值——forEach的return只是终止当前迭代,不会把结果传递给filter的回调函数,相当于逻辑无效。filter的回调函数没有明确返回布尔值,默认返回undefined,而undefined在布尔判断里会被当成false,所以所有数据项都被过滤掉,最终得到空数组。
你的需求是筛选出tags包含所有filter指定标签的项,forEach没法实现这种全匹配的逻辑判断,得用数组的every方法。
解决方案
用every()替代forEach(),every()会检查数组中所有元素是否都满足指定条件:只要有一个元素不满足就返回false,全部满足才返回true,正好匹配你的筛选需求。
修改后的代码:
const data = [ { "tags": [ "madewithout__gluten", "madewithout__nuts" ], "metafields": "Side" }, { "tags": [ "madewithout__gluten" ], "metafields": "Side" }, { "tags": [ "madewithout__nuts" ], "metafields": "Side" } ] const filters = ['gluten', 'nuts'] const result = data.filter((v) => { // 检查当前项的tags是否包含所有filter对应的完整标签 return filters.every(tag => v.tags.includes(`madewithout__${tag}`)); }); console.log(result);
运行这段代码就能得到你想要的预期结果。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

