You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:27:16