如何重组 JSON 以匹配 Flutter 中的数据类型?

How to regroup JSON to match data types in Flutter?

这里的目标是按日期对JSON数据进行分组,并在Flutter中将其转换为对象。

API 的服务我正在使用 returns JSON 这种格式:

        {
            "id": 1,
            "name": "Article Name",
            "created_at": "2020-01-10T00:33:09.000000Z",
        },
        {
            "id": 2,
            "name": "Article Name",
            "created_at": "2020-01-10T00:33:09.000000Z",
        },

我需要将其转换为以下格式:

  Map<String, List<Article>> ArticleHistory = {
    '04.08.2020': [
      Article(id: 16, name: 'Article Name'),
      Article(id: 15, name: 'Article Name'),
      Article(id: 14, name: 'Article Name'),
      Article(id: 13, name: 'Article Name'),
    ],
    '03.08.2020': [
      Article(id: 12, name: 'Article Name'),
      Article(id: 11, name: 'Article Name'),
      Article(id: 10, name: 'Article Name'),
      Article(id: 9, name: 'Article Name'),
    ],
    '02.08.2020': [
      Article(id: 8, name: 'Article Name'),
      Article(id: 7, name: 'Article Name'),
      Article(id: 6, name: 'Article Name'),
      Article(id: 5, name: 'Article Name'),
    ],
    '01.08.2020': [
      Article(id: 4, name: 'Article Name'),
      Article(id: 3, name: 'Article Name'),
      Article(id: 2, name: 'Article Name'),
      Article(id: 1, name: 'Article Name'),
    ],
  };        

如何实现?

让你拥有以下格式的数据:

List<Map<String, dynamic>> articlesListJson = [
  {
    "id": 1,
    "name": "Article 1",
    "created_at": "2020-08-01T00:30:00.000000Z",
  },
  {
    "id": 2,
    "name": "Article 2",
    "created_at": "2020-08-01T00:45:00.000000Z",
  },
  {
    "id": 3,
    "name": "Article 3",
    "created_at": "2020-08-02T00:00:00.000000Z",
  },
];

(如果您有 json 字符串,请使用 jsonDecode 函数将其解析为 Dart 的 ListMap

因为你想将日期存储为 dd.mm.yyyy 字符串,写一个辅助函数来将 2020-08-01T00:30:00.000000Z 转换为 01.08.2020:

String extractDateString(String dateTimeString) {
  DateTime dateTime = DateTime.parse(dateTimeString);
  String day = dateTime.day.toString().padLeft(2, '0');
  String month = dateTime.month.toString().padLeft(2, '0');
  String year = dateTime.year.toString().padLeft(4, '0');
  return '$day.$month.$year';
}

然后您将能够按日期对列表进行分组:

Map<String, List<Map<String, dynamic>>> articleGroupsJson = groupBy(
  articlesListJson,
  (a) => extractDateString(a['created_at']),
);
// {'01.08.2020': [{...}, {...}], '02.08.2020': [{...}]}

groupBy 来自 collection package. Depend on it or just copy-paste function source.

现在将每个 Map<String, dynamic> 解析为 Article class:

class Article {
  int id;
  String name;
  
  Article({this.id, this.name});
}

以标准方式:

Article parseArticle(Map<String, dynamic> map) {
  return Article(
    id: map['id'],
    name: map['name'],
  );
}

因为数据已经分组,而不是简单地映射列表,您需要映射组,并为每个组映射其值(即列表)

Map<String, List<Article>> articleGroups = articleGroupsJson.map(
  (date, list) => MapEntry(
    date,
    list.map(parseArticle).toList(),
  ),
);

现在articleGroups有你想要的结构