如何编写Dart函数汇总API状态数据并映射到目标Map?
解决方案
步骤拆解
把需求拆成三个核心模块,逐个实现后整合:
- 处理单个数据项,计算各目标分类的占比映射值
- 遍历所有API返回数据,逐个处理并更新目标Map
- 兼容边界情况(如
states: null、总和为0等)
完整实现代码
void main() { // 初始化目标Map final Map<String, List<int>> states = { "Anxiety": [], "Stress": [], "Involvement": [], "Relaxation": [], "Fatigue": [], }; // API返回的原始数据 final List<Map<String, dynamic>> data = [ { "id": 1, "states": { "Anxiety": 2, "Stress": 1, "Chronic Fatigue": 1, }, }, { "id": 2, "states": { "Stress": 1, "Fatigue": 1, "Involvement": 1, "Slight Fatigue": 2, "Anxiety": 5, "Relaxation": 2, "Chronic Fatigue": 3, }, }, { "id": 3, "states": null, // 测试边界:states为null的情况 }, ]; // 定义Fatigue相关的所有子分类 const fatigueSubtypes = ["Fatigue", "Slight Fatigue", "Chronic Fatigue"]; // 目标分类列表 const targetCategories = ["Anxiety", "Stress", "Involvement", "Relaxation", "Fatigue"]; // 处理单个数据项,返回各分类对应的映射值 Map<String, int> processItem(Map<String, dynamic>? itemStates) { final result = { "Anxiety": 0, "Stress": 0, "Involvement": 0, "Relaxation": 0, "Fatigue": 0, }; if (itemStates == null) return result; // 计算当前项的states数值总和 int total = itemStates.values.fold(0, (sum, value) => sum + (value as int)); if (total == 0) return result; // 避免除以0的异常 // 汇总Fatigue类的总数值 int fatigueTotal = 0; for (final subtype in fatigueSubtypes) { fatigueTotal += itemStates[subtype] ?? 0; } // 计算Fatigue的占比并映射数值 final fatigueRatio = fatigueTotal / total; result["Fatigue"] = _mapRatioToValue(fatigueRatio); // 处理其他分类的占比映射 for (final category in targetCategories) { if (category == "Fatigue") continue; final value = itemStates[category] ?? 0; final ratio = value / total; result[category] = _mapRatioToValue(ratio); } return result; } // 将占比转换为0-3的对应数值 int _mapRatioToValue(double ratio) { if (ratio >= 0.5) return 3; if (ratio >= 0.25) return 2; if (ratio > 0) return 1; return 0; } // 遍历所有数据项,更新目标Map的数组 for (final item in data) { final itemResult = processItem(item["states"]); for (final category in targetCategories) { states[category]!.add(itemResult[category]!); } } // 打印验证结果 print(states); }
代码说明
- 常量抽离:把Fatigue子分类和目标分类定义为常量,后续修改分类时只需改动此处,无需调整核心逻辑。
- 单数据项处理:
processItem函数单独负责单个数据的计算,包括空值处理、总和计算、占比映射,逻辑独立清晰。 - 占比映射函数:
_mapRatioToValue单独抽离规则,后续修改映射标准(如调整阈值)时直接修改该函数即可。 - 边界兼容:处理了
states: null和总和为0的情况,避免运行时异常。
内容的提问来源于stack exchange,提问作者newbiras
相关产品推荐
相关产品推荐

