Flutter:如何将API返回的JSON对象转为自定义Hour对象列表?
问题:将键值对结构的JSON转换为List对象
我正尝试从API获取数据并转换为自定义对象类,但收到的JSON响应并非数组,而是以时段为键的JSON对象,结构如下:
{"00-01": {"date": "24-08-2022","hour": "00-01","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 617.5,"units": "€/Mwh"},"01-02": {"date": "24-08-2022","hour": "01-02","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 640.05,"units": "€/Mwh"},"02-03": {"date": "24-08-2022","hour": "02-03","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 670.26,"units": "€/Mwh"},"03-04": {"date": "24-08-2022","hour": "03-04","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 683.64,"units": "€/Mwh"},"04-05": {"date": "24-08-2022","hour": "04-05","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 692.88,"units": "€/Mwh"},"05-06": {"date": "24-08-2022","hour": "05-06","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 681.87,"units": "€/Mwh"},"06-07": {"date": "24-08-2022","hour": "06-07","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 624.35,"units": "€/Mwh"},"07-08": {"date": "24-08-2022","hour": "07-08","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 624.82,"units": "€/Mwh"},"08-09": {"date": "24-08-2022","hour": "08-09","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 623.24,"units": "€/Mwh"},"09-10": {"date": "24-08-2022","hour": "09-10","is-cheap": false,"is-under-avg": true,"market": "PVPC","price": 558.55,"units": "€/Mwh"},"10-11": {"date": "24-08-2022","hour": "10-11","is-cheap": false,"is-under-avg": true,"market": "PVPC","price": 511.3,"units": "€/Mwh"},"11-12": {"date": "24-08-2022","hour": "11-12","is-cheap": false,"is-under-avg": true,"market": "PVPC","price": 493.36,"units": "€/Mwh"},"12-13": {"date": "24-08-2022","hour": "12-13","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 484.42,"units": "€/Mwh"},"13-14": {"date": "24-08-2022","hour": "13-14","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 487.58,"units": "€/Mwh"},"14-15": {"date": "24-08-2022","hour": "14-15","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 426.72,"units": "€/Mwh"},"15-16": {"date": "24-08-2022","hour": "15-16","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 418.28,"units": "€/Mwh"},"16-17": {"date": "24-08-2022","hour": "16-17","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 422.18,"units": "€/Mwh"},"17-18": {"date": "24-08-2022","hour": "17-18","is-cheap": true,"is-under-avg": true,"market": "PVPC","price": 430.63,"units": "€/Mwh"},"18-19": {"date": "24-08-2022","hour": "18-19","is-cheap": false,"is-under-avg": true,"market": "PVPC","price": 495.26,"units": "€/Mwh"},"19-20": {"date": "24-08-2022","hour": "19-20","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 579.65,"units": "€/Mwh"},"20-21": {"date": "24-08-2022","hour": "20-21","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 614.08,"units": "€/Mwh"},"21-22": {"date": "24-08-2022","hour": "21-22","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 625.97,"units": "€/Mwh"},"22-23": {"date": "24-08-2022","hour": "22-23","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 582.99,"units": "€/Mwh"},"23-24": {"date": "24-08-2022","hour": "23-24","is-cheap": false,"is-under-avg": false,"market": "PVPC","price": 617.25,"units": "€/Mwh"}}
我希望将该结果转换为List<Hour>,其中每个元素为Hour类实例。尝试过执行LightPrice lightPrice = LightPrice.fromJson(jsonDecode(response.body));但所有字段均为null,也用过JSON转Dart工具但无法实现转换。请问如何将该响应转换为自定义的Hour和对应的列表对象?
解决方案
1. 定义Hour数据类
根据JSON结构定义Hour类,手动映射JSON中的蛇形命名字段到Dart的驼峰命名:
class Hour { final String date; final String hour; final bool isCheap; final bool isUnderAvg; final String market; final double price; final String units; Hour({ required this.date, required this.hour, required this.isCheap, required this.isUnderAvg, required this.market, required this.price, required this.units, }); // 从JSON对象转换为Hour实例 factory Hour.fromJson(Map<String, dynamic> json) { return Hour( date: json['date'] as String, hour: json['hour'] as String, isCheap: json['is-cheap'] as bool, isUnderAvg: json['is-under-avg'] as bool, market: json['market'] as String, price: (json['price'] as num).toDouble(), units: json['units'] as String, ); } }
2. 处理JSON转换逻辑
API返回的是Map<String, dynamic>(键为时段,值为小时数据),而非数组。只需遍历Map的values集合,将每个值转换为Hour实例,最终收集为List<Hour>:
import 'dart:convert'; // 假设response是API返回的响应对象 final Map<String, dynamic> jsonMap = jsonDecode(response.body); // 转换为List<Hour> List<Hour> hourList = jsonMap.values .map((hourJson) => Hour.fromJson(hourJson as Map<String, dynamic>)) .toList();
3. 原方法失效原因
你之前尝试的LightPrice.fromJson失败,是因为LightPrice类的结构是按固定字段定义的,但API返回的是动态键的Map,没有与LightPrice类匹配的字段,所以所有字段都会被解析为null。普通JSON转Dart工具通常默认生成对应固定结构的类,无法处理这种动态键的Map转列表的场景。
内容的提问来源于stack exchange,提问作者Andrés Cabrera Diaz
相关产品推荐
相关产品推荐

