多属性条件过滤数组:筛选含正负混合支出的父级分组
按父级分组过滤支出数组,保留子项同时包含正负支出的父级元素
现有一个包含parent、child及多笔expense(数量可超过3个)的数组,需求是按parent分组过滤数组,仅保留其子项支出同时包含正数和负数的父级对应的所有元素,排除子项支出全为正数或全为负数的父级。
输入数组
let inputArray1 = [ { 'parent':'A', 'child':'RST', 'expense1':1, 'expense2':2, 'expense3':3, }, { 'parent':'A', 'child':'EST', 'expense1':4, 'expense2':5, 'expense3':6, }, { 'parent':'A', 'child':'QST', 'expense1':4, 'expense2':2, 'expense3':6, }, { 'parent':'B', 'child':'EST', 'expense1':1, 'expense2':2, 'expense3':-3, // 负数支出 }, { 'parent':'B', 'child':'VST', 'expense1':6, 'expense2':2, 'expense3':3, }, { 'parent':'B', 'child':'NST', 'expense1':3, 'expense2':8, 'expense3':7, }, { 'parent':'C', 'child':'UST', 'expense1':-8, 'expense2':-2, 'expense3':3, // 正数支出 }, { 'parent':'C', 'child':'PST', 'expense1':-6, 'expense2':-5, 'expense3':-3, }, { 'parent':'C', 'child':'LST', 'expense1':-3, 'expense2':-8, 'expense3':-7, }, { 'parent':'D', 'child':'WST', 'expense1':-8, 'expense2':-2, 'expense3':-3, }, { 'parent':'D', 'child':'CST', 'expense1':-6, 'expense2':-5, 'expense3':-3, }, { 'parent':'D', 'child':'KST', 'expense1':-3, 'expense2':-8, 'expense3':-7, } ]
预期输出数组
仅保留父级B和C对应的元素,因其子项支出同时包含正数和负数:
let resultArray = [ { 'parent':'B', 'child':'EST', 'expense1':1, 'expense2':2, 'expense3':-3, }, { 'parent':'B', 'child':'VST', 'expense1':6, 'expense2':2, 'expense3':3, }, { 'parent':'B', 'child':'NST', 'expense1':3, 'expense2':8, 'expense3':7, }, { 'parent':'C', 'child':'UST', 'expense1':-8, 'expense2':-2, 'expense3':3, }, { 'parent':'C', 'child':'PST', 'expense1':-6, 'expense2':-5, 'expense3':-3, }, { 'parent':'C', 'child':'LST', 'expense1':-3, 'expense2':-8, 'expense3':-7, }, ]
解决方案
实现思路
- 遍历数组,统计每个父级下是否存在正数支出和负数支出,只要该父级下有任意子项包含正数/负数,就标记对应状态为true
- 筛选出同时存在正负支出的父级列表
- 再次过滤原数组,只保留属于这些有效父级的元素
代码实现
// 统计每个父级的支出正负状态 const parentExpenseStatus = inputArray1.reduce((acc, item) => { const parent = item.parent; // 提取当前项的所有支出数值(排除非数字类型的字段) const expenses = Object.values(item).filter(val => typeof val === 'number'); const hasPositive = expenses.some(num => num > 0); const hasNegative = expenses.some(num => num < 0); // 初始化父级状态 if (!acc[parent]) { acc[parent] = { hasPositive: false, hasNegative: false }; } // 更新状态:只要有一个子项满足,就保持true acc[parent].hasPositive = acc[parent].hasPositive || hasPositive; acc[parent].hasNegative = acc[parent].hasNegative || hasNegative; return acc; }, {}); // 筛选出同时包含正负支出的父级 const validParents = Object.keys(parentExpenseStatus).filter(parent => { const status = parentExpenseStatus[parent]; return status.hasPositive && status.hasNegative; }); // 过滤原数组,得到结果 const result = inputArray1.filter(item => validParents.includes(item.parent)); console.log(result);
代码说明
- 使用
reduce高效统计每个父级的状态,避免重复遍历 - 通过
Object.values结合filter提取所有支出字段,兼容任意数量的expense项 - 两次
filter操作分别筛选有效父级和对应元素,逻辑清晰易维护
内容的提问来源于stack exchange,提问作者RV.
相关产品推荐
相关产品推荐

