如何用JS/JQuery基于动态条件数组过滤对象数组?
问题描述
我有一个包含200余条记录的对象数组,单条记录结构示例如下:
[ { "id": "86106175277", "createdAt": "2022-09-26T20:57:10.850Z", "updatedAt": "2023-02-10T22:23:32.721Z", "publishedAt": "2023-02-10T22:46:29.561Z", "values": { "primary_image": { "url": "N17D0087-1.jpg", "width": 1920, "height": 1282, "altText": "", "type": "image" }, "matterport": "Jabw7wfaoLg", "sleeps": 4, "brochure": "Jay-Flight-SLX-Brochure-2023.pdf", "visible": 1, "model_id_": "154BH", "color": "FARMHOUSE", "year": "2022", "black": 19.9, "length": "18", "chassis": "N/A", "type": "Travel Trailer", "floorplan": "6644-154BH.png", "condition": "USED", "gray": 19.9, "engine": "N/A", "fuel_capacity": "N/A", "msrp": "30070", "sales_price": 19988, "model": "SLX", "location": "Vogt RV - Towables", "sku": "N17D0087", "fresh": 10, "make": "JAYCO" }, "path": "jayco-slx-154bh-2012", "name": "JAYCO SLX 154BH 2022", "childTableId": "0", "isSoftEditable": false }, { "id": "86106175278", "createdAt": "2022-09-26T20:57:10.857Z", "updatedAt": "2023-02-10T22:23:36.289Z", "publishedAt": "2023-02-10T22:46:29.561Z", "values": { "primary_image": { "url": "N17D0334/N17D0334-1.jpg", "width": 1920, "height": 1282, "altText": "", "type": "image" }, "matterport": "Jabw7wfaoLg", "sleeps": 4, "brochure": "Jay-Flight-SLX-Brochure-2023.pdf", "visible": 1, "model_id_": "154BH", "color": "FARMHOUSE", "year": "2022", "black": 19.9, "length": "18", "chassis": "N/A", "type": "Travel Trailer", "floorplan": "6644-154BH.png", "condition": "USED", "gray": 19.9, "engine": "N/A", "fuel_capacity": "N/A", "msrp": "32392", "sales_price": 27533, "model": "SLX", "location": "Vogt RV - Towables", "sku": "N17D0334", "fresh": 10, "make": "JAYCO" }, "path": "jayco-slx-154bh-2012-2", "name": "JAYCO SLX 154BH 2022", "childTableId": "0", "isSoftEditable": false } ]
另有一个由复选框选择动态生成的条件数组,示例如下:
单个条件:
[ { "category": "location", "value": "Vogt RV - Motorhomes" } ]
多个条件(同一分类下多值为OR逻辑,不同分类为AND逻辑):
[ { "category": "location", "value": "Vogt RV - Motorhomes" }, { "category": "location", "value": "Leisure RV Center" }, { "category": "location", "value": "Vogt RV - Towables" }, { "category": "condition", "value": "NEW" } ]
需要基于条件数组过滤原对象数组,要求同一category下的多个value为OR逻辑,不同category之间为AND逻辑。我尝试了以下代码但未生效:
myArrayFiltered = modelos[0].filter((item) => { return filtersHubDb.every(valo => { return valo.value === item.values[valo.category]; }); });
解决方案
Vanilla JavaScript 实现
原代码使用every()会要求所有条件逐一匹配,但同一分类下的多值需要OR逻辑,因此需要先将条件按category分组,再对每个分组做OR判断,最后确保所有分组条件都满足(AND逻辑)。
代码示例:
// 1. 将条件按分类分组,把同一category的value合并到数组中 const groupedFilters = filtersHubDb.reduce((acc, filter) => { if (!acc[filter.category]) { acc[filter.category] = []; } acc[filter.category].push(filter.value); return acc; }, {}); // 2. 过滤原数组 const myArrayFiltered = modelos[0].filter(item => { // 检查每个分类分组:当前条目必须满足该分类下至少一个值(OR),且所有分类都要满足(AND) return Object.entries(groupedFilters).every(([category, values]) => { return values.includes(item.values[category]); }); });
逻辑说明
reduce()将扁平的条件数组转为按分类分组的对象,比如示例中的多条件会转为:{ location: ["Vogt RV - Motorhomes", "Leisure RV Center", "Vogt RV - Towables"], condition: ["NEW"] }- 过滤时,
every()确保所有分类条件都满足(AND逻辑),每个分类内部用includes()检查条目值是否在该分类的允许值列表中(OR逻辑) - 如果条件数组为空,
groupedFilters是空对象,every()会默认返回true,即返回所有原数组条目,符合业务逻辑
jQuery 实现
逻辑和Vanilla JS一致,仅用jQuery方法替代原生数组API:
// 1. 按分类分组条件 const groupedFilters = {}; $.each(filtersHubDb, function(_, filter) { if (!groupedFilters[filter.category]) { groupedFilters[filter.category] = []; } groupedFilters[filter.category].push(filter.value); }); // 2. 过滤数组 const myArrayFiltered = $.grep(modelos[0], function(item) { let matchesAll = true; $.each(groupedFilters, function(category, values) { if (!values.includes(item.values[category])) { matchesAll = false; return false; // 跳出当前循环 } }); return matchesAll; });
内容的提问来源于stack exchange,提问作者Axel Obscura
相关产品推荐
相关产品推荐

