如何结合双数组数据按保险分类并计算风险值生成指定结构的对象数组
实现思路与完整代码
我来帮你搞定这个数据转换需求,咱们拆解成几个清晰的步骤来实现:
第一步:补充必要的映射表
你已经创建了姓名到保险的映射,不过还需要一个姓名到基线风险的映射,这样能快速获取每个用户的基线值,方便计算riskLevel:
// 姓名 → 基线风险数值的映射(转成number类型避免字符串计算) const baselineRiskMap = new Map(history.map(o => [o.name, parseFloat(o.baseline.risk)]));
第二步:构建分组并处理数据逻辑
我们先通过一个临时对象按保险归集用户数据,最后再转成目标数组格式,这样逻辑更清晰:
const history = [ { name: "Lance", baseline: { risk: "112", age: "45", insurance: "Star" }, }, { name: "Sam", baseline: { risk: "9", age: "21", insurance: "Sigma" }, }, { name: "Jill", baseline: { risk: "15", age: "21", insurance: "Sigma" }, }, { name: "Bill", baseline: { risk: "15", age: "21", insurance: "Mercy" }, }, ]; const current = [ { name: "Lance", item: "PS", "3-Aug-21": "117", "4-Aug-21": "120", "5-Aug-21": "112", }, { name: "Sam", item: "PS", "3-Aug-21": "10.14", "4-Aug-21": "10.2", "5-Aug-21": "10", }, { name: "Jill", item: "PS", "3-Aug-21": "10.14", "4-Aug-21": "10.2", "5-Aug-21": "10", }, { name: "Bill", item: "PS", "3-Aug-21": "10.14", "4-Aug-21": "10.2", "5-Aug-21": "10", }, ]; // 1. 初始化映射表 const historyMap = new Map(history.map(o => [o.name, o.baseline.insurance])); const baselineRiskMap = new Map(history.map(o => [o.name, parseFloat(o.baseline.risk)])); // 2. 临时存储分组数据的对象 const groupedData = {}; // 3. 遍历current数组处理每个用户 current.forEach(user => { const userName = user.name; const userInsurance = historyMap.get(userName); const baselineRisk = baselineRiskMap.get(userName); // 提取所有日期字段(排除name和item) const dateFields = Object.keys(user).filter(key => !['name', 'item'].includes(key)); // 计算每个日期的riskLevel const values = dateFields.map(date => { const currentValue = parseFloat(user[date]); // 计算百分比并保留1位小数 let riskLevel = ((currentValue / baselineRisk) * 100).toFixed(1); // 处理示例中"100.0"转"100"的格式要求 riskLevel = riskLevel.endsWith('.0') ? riskLevel.slice(0, -2) : riskLevel; return { date, riskLevel }; }); // 将用户数据加入对应保险分组 if (!groupedData[userInsurance]) { groupedData[userInsurance] = []; } groupedData[userInsurance].push({ name: userName, values }); }); // 4. 将临时分组对象转换为目标数组格式 const filteredData = Object.entries(groupedData).map(([insurance, details]) => ({ insurance, details })); console.log(filteredData);
关键细节说明
- 用
parseFloat把字符串类型的风险值转成数值,避免字符串除法的错误; - 通过
Object.keys(user).filter动态提取日期字段,不用硬编码日期,适配更多日期场景; - 处理了
toFixed(1)后末尾为.0的情况,和你给出的示例输出格式完全一致; - 临时分组对象
groupedData先按保险归集用户,最后转数组的方式,比直接操作目标数组更直观。
内容的提问来源于stack exchange,提问作者moys
相关产品推荐
相关产品推荐

