如何用Lodash或原生JS基于display对象筛选alarm对象内容?
基于display开关筛选告警信息的优雅实现方案
刚好碰到过类似的场景,给你两个简洁的实现方案,原生JS和Lodash的都有,核心逻辑一气呵成,不用额外写辅助函数:
原生JS实现
这个方案利用ES6的数组扩展、flat()、flatMap()和Set去重,逻辑清晰且高效:
const display = { 0: false, 1: true, 2: true, 3: true, ACK: false, MASKED: false, SHELVED: false }; const alarms = { inAlarm: { 0:["A"], 1:["B"], 2:["C"], 3:["D"] }, latched: { 1:[], 2:["C"], 3:[] }, connectionError:["E"], ACK:["F"], SHELVED:["G"], MASKED:[], }; const result = [...new Set([ // 先收集所有latched的内容(强制包含) ...Object.values(alarms.latched).flat(), // 根据display开关筛选其他告警内容 ...Object.entries(display).flatMap(([key, enabled]) => { if (!enabled) return []; // 数字key从inAlarm中取,字符串key直接从alarms根节点取 const source = isNaN(Number(key)) ? alarms[key] : alarms.inAlarm[key]; return source || []; }) ])]; console.log(result); // 输出: ["B","C","D"]
逻辑说明
- 首先通过
Object.values(alarms.latched).flat()把latched下的所有告警内容拉平收集,这部分是强制保留的; - 遍历display的键值对,用
flatMap过滤出开关为true的项:- 如果是数字key,从
alarms.inAlarm中取对应告警数组; - 如果是字符串key(比如ACK、MASKED),直接从
alarms根节点取对应数组;
- 如果是数字key,从
- 最后用
Set去重(避免latched和其他告警源的重复内容),再转成数组得到最终结果。
Lodash实现
如果项目里已经在用Lodash,这个方案会更简洁,利用Lodash的工具函数减少原生API的繁琐处理:
const _ = require('lodash'); const display = { 0: false, 1: true, 2: true, 3: true, ACK: false, MASKED: false, SHELVED: false }; const alarms = { inAlarm: { 0:["A"], 1:["B"], 2:["C"], 3:["D"] }, latched: { 1:[], 2:["C"], 3:[] }, connectionError:["E"], ACK:["F"], SHELVED:["G"], MASKED:[], }; const result = _.uniq(_.flatten([ _.flatten(_.values(alarms.latched)), _.flatMap(display, (enabled, key) => { if (!enabled) return []; const source = _.isNaN(_.toNumber(key)) ? alarms[key] : alarms.inAlarm[key]; return source || []; }) ])); console.log(result); // 输出: ["B","C","D"]
逻辑说明
和原生JS的核心逻辑一致,只是用Lodash的_.values、_.flatten、_.flatMap、_.uniq这些工具函数替代原生API,代码更紧凑,处理边缘情况(比如非标准数字key)的兼容性更好。
内容的提问来源于stack exchange,提问作者Fonty
相关产品推荐
相关产品推荐

