
本文详解如何遍历嵌套对象数组,按 type 分组统计已选选项数量,并为每个选项动态添加 disableType 布尔属性:若该类型下所有选项均被至少选择过一次(跨行汇总),则设为 true,否则为 false。
本文详解如何遍历嵌套对象数组,按 `type` 分组统计已选选项数量,并为每个选项动态添加 `disabletype` 布尔属性:若该类型下所有选项均被至少选择过一次(跨行汇总),则设为 `true`,否则为 `false`。
在实际业务场景中(如多预算表单的联动控制),常需根据全局选择状态动态禁用整类下拉选项。核心逻辑分为三步:分组计数 → 跨行聚合 → 属性注入。下面以 tableRows 数据为例,给出完整、健壮、可复用的实现方案。
✅ 步骤一:按 type 统计总选项数与已选总数
首先遍历全部 dropdownOptions,构建两个映射表:
-
totalPerType:记录每种type下的总选项数量(固定值); -
chosenPerType:记录该type在所有行中被选中的总次数(注意:此处是累加,而非“是否至少被选过一次”——但后续判断只需关注是否 ≥1)。
const totalPerType = {};
const chosenPerType = {};
// 一次性遍历所有行和选项,完成统计
tableRows.forEach(row => {
row.dropdownOptions.forEach(opt => {
// 统计每 type 的总数量
totalPerType[opt.type] = (totalPerType[opt.type] || 0) + 1;
// 统计每 type 的已选总数(true 计 1,false 不计)
if (opt.chosen) {
chosenPerType[opt.type] = (chosenPerType[opt.type] || 0) + 1;
}
});
});
⚠️ 注意:题目要求是“每个 type 下所有选项是否都被至少选择过一次”,即只要
chosenPerType[type] >= totalPerType[type],就说明该类型已“满选”。由于每个选项id唯一且跨行复用,此逻辑天然支持多行协同判定。
✅ 步骤二:为每个选项注入 disableType
再次遍历所有 dropdownOptions,对每个选项判断其所属 type 是否已达“全选”状态:
tableRows.forEach(row => {
row.dropdownOptions.forEach(opt => {
const type = opt.type;
// 若该 type 的已选总数 ≥ 总数,则 disableType = true
opt.disableType = (chosenPerType[type] || 0) >= (totalPerType[type] || 0);
});
});
此写法比原答案中仅比较相等更鲁棒——即使因数据异常导致 chosenPerType[type] > totalPerType[type](例如重复提交),仍能正确置为 true。
✅ 完整可运行示例
// 假设 tableRows 已定义(同题干)
const totalPerType = {};
const chosenPerType = {};
tableRows.forEach(row => {
row.dropdownOptions.forEach(opt => {
totalPerType[opt.type] = (totalPerType[opt.type] || 0) + 1;
if (opt.chosen) {
chosenPerType[opt.type] = (chosenPerType[opt.type] || 0) + 1;
}
});
});
// 注入 disableType 属性(不可变操作建议使用 map + structuredClone,此处为就地修改)
tableRows.forEach(row => {
row.dropdownOptions.forEach(opt => {
opt.disableType = (chosenPerType[opt.type] || 0) >= (totalPerType[opt.type] || 0);
});
});
console.log(tableRows); // 输出符合预期的结果
? 关键注意事项
-
不要混淆“单行内全选”与“跨行累计全选”:本需求是后者,即
Expenditure: Administration类型共 3 个选项,只要这 3 个选项在任意行中被分别选中(如 UUID1 在 Budget1、UUID2 在 Budget2、UUID3 在 Budget3),即满足chosenPerType["Expenditure: Administration"] === 3,触发disableType: true。 -
避免副作用:若原始数据需保留,应先深拷贝(如
JSON.parse(JSON.stringify(tableRows))或使用structuredClone)再处理。 -
边界防护:使用
(chosenPerType[type] || 0)防止undefined参与比较,提升代码健壮性。 -
性能提示:对于超大数据集(如 >10,000 选项),可考虑用
Map替代普通对象提升查找效率,但本场景下无明显必要。
通过以上方法,你不仅能精准实现 disableType 的智能标记,还能轻松扩展为其他基于类型聚合的动态行为(如高亮、分组摘要、权限控制等)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











