Flutter/Dart如何筛选指定月份的cardBillsTotal数据并保存
需求与实现指导
原始数据结构
{ "results": [ { "firstName": "Thomas", "lastName": "Papioanou", "userID": 238, "month": 5, "year": 2022, "cardBillsTotal": [ { "serial": "884221337251", "value": 1.0450, "vat": 0.2508, "total": 1.2958, "energy": 0 } ] }, { "firstName": "Thomas", "lastName": "Papioanou", "userID": 238, "month": 6, "year": 2022, "cardBillsTotal": [ { "serial": "884221337251", "value": 3.4034, "vat": 0.8168, "total": 4.2202, "energy": 0 } ] }, { "firstName": "Thomas", "lastName": "Papioanou", "userID": 238, "month": 7, "year": 2022, "cardBillsTotal": [ { "serial": "884221337251", "value": 2.0900, "vat": 0.5016, "total": 2.5916, "energy": 0 } ] }, { "firstName": "Thomas", "lastName": "Papioanou", "userID": 238, "month": 5, "year": 2022, "cardBillsTotal": [ { "serial": "941368618045", "value": 2.2884, "vat": 0.5492, "total": 2.8376, "energy": 0 } ] }, { "firstName": "Thomas", "lastName": "Papioanou", "userID": 238, "month": 6, "year": 2022, "cardBillsTotal": [ { "serial": "941368618045", "value": 1.1083, "vat": 0.2660, "total": 1.3743, "energy": 0 } ] } ], "count": 5 }
需求
筛选出month字段值等于5的条目,并提取其中的cardBillsTotal数组进行存储。
现有请求代码
Future<List<Evsebillall>> fetchall() async { String? token = await this.storage.read(key: "token"); Map<String, String> headers = { "Content-Type": "application/json", "Accept": "application/json", "Authorization": "Bearer " + (token ?? ""), }; final response = await http.get(Uri.parse( this.serverIP + ':' + this.serverPort + '/user/contractedChargeTransactionsList?page=1&limit=10'), headers: headers); if (response.statusCode == 200) { setState(() { cardBillsall = jsonDecode(response.body)["results"] as List; print(cardBillsall); var result = cardBillsall.map((e) => Evsebillall.fromJson(e)).toList(); print (data); }); return cardBillsall.map((e) => Evsebillall.fromJson(e)).toList(); } else{ throw Exception('Failed to load Bills'); } }
无效尝试代码
var data = cardBillsall.map((e) => e["month"]=5).toList();
正确实现方案
你的无效代码问题在于使用了赋值运算符=,这会将所有条目的month强制改为5,而非筛选符合条件的条目。正确逻辑是先筛选、再提取,分两种场景实现:
1. 直接处理原始JSON List(不转模型)
如果不需要将数据转为Evsebillall模型,直接在setState中处理:
if (response.statusCode == 200) { setState(() { cardBillsall = jsonDecode(response.body)["results"] as List; // 第一步:筛选month等于5的条目 var filteredEntries = cardBillsall.where((entry) => entry["month"] == 5).toList(); // 第二步:提取所有符合条件的cardBillsTotal,合并为一个大列表 List<dynamic> allCardBillsTotal = filteredEntries.expand((entry) => entry["cardBillsTotal"] as List).toList(); // 若需保留每个条目对应的cardBillsTotal数组,改用以下代码: // List<List<dynamic>> cardBillsTotalList = filteredEntries.map((entry) => entry["cardBillsTotal"] as List).toList(); print(allCardBillsTotal); // 打印验证结果 }); // 其他逻辑... }
2. 转为Evsebillall模型后处理
如果需要基于模型操作,先将JSON转为模型列表,再筛选提取:
if (response.statusCode == 200) { setState(() { cardBillsall = jsonDecode(response.body)["results"] as List; var result = cardBillsall.map((e) => Evsebillall.fromJson(e)).toList(); // 筛选month=5的模型实例 var filteredModels = result.where((model) => model.month == 5).toList(); // 提取cardBillsTotal(需确保Evsebillall类中定义了cardBillsTotal字段) List<CardBillTotal> allCardBills = filteredModels.expand((model) => model.cardBillsTotal).toList(); print(allCardBills); }); return result; }
关键要点
- 使用
where()方法完成筛选,判断条件为entry["month"] == 5(原始JSON)或model.month ==5(模型实例) - 使用
expand()可将多个子数组合并为一个大列表;若需保留原条目与子数组的对应关系,改用map()即可 - 注意类型转换,确保
cardBillsTotal被正确识别为List类型
内容的提问来源于stack exchange,提问作者Bill Tertis
相关产品推荐
相关产品推荐

