如何解析飞镖中的动态 JSON 键
How to parse dynamic JSON keys in dart
我有一个 API returns JSON 带有动态键,即每个 GET
请求都会更改键值。
例如:这是 JSON.
的格式
我在 dart 中有一个书本模型,
class Book {
String id = "";
String title = "";
Book();
Book.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
}
static List<Book> listFromJson(List<dynamic> json) {
return json.map((val) => Book.fromJson(val)).toList();
}
}
和JSON响应,
{
"Recommended For You" : [
{
"id" : "001",
"title" : "title001"
},
...
],
"Thrillers" : [
{
"id" : "005",
"title" : "title005"
},
...
]
}
考虑到类型(如 Thrillers
)可以改变(即它是动态的并且可能因每个用户而改变),如何根据类型将其解析为书籍列表?
编辑 1
Thrillers
和 Recommended For You
不是恒定的,有时它可能会更改为 Horror
和 Romantic
或其他。这是动态
编辑 2:解决方案
感谢@lrn 的解决方案,我想出了一个新的 Class
class Recommendations {
String recommendationType;
List<Book> recommendations;
@override
String toString() {
return 'Recomendations[title: $recommendationType]';
}
Recommendations.fromJson(MapEntry<String, dynamic> json) {
if (json == null) return;
this.recommendationType = json.key;
this.recommendations = Book.listFromJson(json.value);
}
static List<Recommendations> listFromJson(Map<String, dynamic> json) {
return json == null
? List<Recommendations>.empty()
: json.entries
.map((value) => new Recommendations.fromJson(value))
.toList();
}
}
您的响应模型包含两个不同的数组,recommendedForYou
和 thrillers
。所以,你可以这样处理:
// To parse this JSON data, do
//
// final responseModel = responseModelFromJson(jsonString);
import 'dart:convert';
ResponseModel responseModelFromJson(String str) => ResponseModel.fromJson(json.decode(str));
String responseModelToJson(ResponseModel data) => json.encode(data.toJson());
class ResponseModel {
ResponseModel({
this.recommendedForYou,
this.thrillers,
});
List<Book> recommendedForYou;
List<Book> thrillers;
factory ResponseModel.fromJson(Map<String, dynamic> json) => ResponseModel(
recommendedForYou: json["Recommended For You"] == null ? null : List<Book>.from(json["Recommended For You"].map((x) => Book.fromJson(x))),
thrillers: json["Thrillers"] == null ? null : List<Book>.from(json["Thrillers"].map((x) => Book.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Recommended For You": recommendedForYou == null ? null : List<dynamic>.from(recommendedForYou.map((x) => x.toJson())),
"Thrillers": thrillers == null ? null : List<dynamic>.from(thrillers.map((x) => x.toJson())),
};
}
class Book {
Book({
this.id,
this.title,
});
String id;
String title;
factory Book.fromJson(Map<String, dynamic> json) => Book(
id: json["id"] == null ? null : json["id"],
title: json["title"] == null ? null : json["title"],
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"title": title == null ? null : title,
};
}
您可以使用此 site 将您的 json 转换为任何飞镖模型。
如果您不知道键,但知道它是一个 JSON 地图,其中的值是您要查找的图书列表,我会写:
List<Book> parseCategorizedBooksJson(Map<String, dynamic> json) =>
[for (var books in json.values) ...Book.listFromJson(books)];
或
List<Book> parseCategorizedBooksJson(Map<String, dynamic> json) =>
[for (var books in json.values)
for (var book in books) Book.fromJson(book)];
(避免建立中间书籍列表)。
有了这个,您只需迭代外部地图的 values,并忽略键。 JSON 映射只是普通的 Dart Map
s,您可以访问键作为 .keys
(然后遍历它们而无需提前知道它们)并访问值作为 .values
(并完全忽略键)。
每个值都是一个图书列表,您可以使用现有的静态函数对其进行解析。
要包含该类型,您必须说明您希望如何记住该类型。最简单的就是将数据保留为地图:
var categoriedBooks = {for (var genre in json)
genre: Book.listFromJson(json[genre])
};
这将构建一个具有相同键(流派)的地图,但其中的值现在是 Book
s 的列表。
我有一个 API returns JSON 带有动态键,即每个 GET
请求都会更改键值。
例如:这是 JSON.
的格式我在 dart 中有一个书本模型,
class Book {
String id = "";
String title = "";
Book();
Book.fromJson(Map<String, dynamic> json) {
id = json['id'];
title = json['title'];
}
static List<Book> listFromJson(List<dynamic> json) {
return json.map((val) => Book.fromJson(val)).toList();
}
}
和JSON响应,
{
"Recommended For You" : [
{
"id" : "001",
"title" : "title001"
},
...
],
"Thrillers" : [
{
"id" : "005",
"title" : "title005"
},
...
]
}
考虑到类型(如 Thrillers
)可以改变(即它是动态的并且可能因每个用户而改变),如何根据类型将其解析为书籍列表?
编辑 1
Thrillers
和 Recommended For You
不是恒定的,有时它可能会更改为 Horror
和 Romantic
或其他。这是动态
编辑 2:解决方案
感谢@lrn 的解决方案,我想出了一个新的 Class
class Recommendations {
String recommendationType;
List<Book> recommendations;
@override
String toString() {
return 'Recomendations[title: $recommendationType]';
}
Recommendations.fromJson(MapEntry<String, dynamic> json) {
if (json == null) return;
this.recommendationType = json.key;
this.recommendations = Book.listFromJson(json.value);
}
static List<Recommendations> listFromJson(Map<String, dynamic> json) {
return json == null
? List<Recommendations>.empty()
: json.entries
.map((value) => new Recommendations.fromJson(value))
.toList();
}
}
您的响应模型包含两个不同的数组,recommendedForYou
和 thrillers
。所以,你可以这样处理:
// To parse this JSON data, do
//
// final responseModel = responseModelFromJson(jsonString);
import 'dart:convert';
ResponseModel responseModelFromJson(String str) => ResponseModel.fromJson(json.decode(str));
String responseModelToJson(ResponseModel data) => json.encode(data.toJson());
class ResponseModel {
ResponseModel({
this.recommendedForYou,
this.thrillers,
});
List<Book> recommendedForYou;
List<Book> thrillers;
factory ResponseModel.fromJson(Map<String, dynamic> json) => ResponseModel(
recommendedForYou: json["Recommended For You"] == null ? null : List<Book>.from(json["Recommended For You"].map((x) => Book.fromJson(x))),
thrillers: json["Thrillers"] == null ? null : List<Book>.from(json["Thrillers"].map((x) => Book.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Recommended For You": recommendedForYou == null ? null : List<dynamic>.from(recommendedForYou.map((x) => x.toJson())),
"Thrillers": thrillers == null ? null : List<dynamic>.from(thrillers.map((x) => x.toJson())),
};
}
class Book {
Book({
this.id,
this.title,
});
String id;
String title;
factory Book.fromJson(Map<String, dynamic> json) => Book(
id: json["id"] == null ? null : json["id"],
title: json["title"] == null ? null : json["title"],
);
Map<String, dynamic> toJson() => {
"id": id == null ? null : id,
"title": title == null ? null : title,
};
}
您可以使用此 site 将您的 json 转换为任何飞镖模型。
如果您不知道键,但知道它是一个 JSON 地图,其中的值是您要查找的图书列表,我会写:
List<Book> parseCategorizedBooksJson(Map<String, dynamic> json) =>
[for (var books in json.values) ...Book.listFromJson(books)];
或
List<Book> parseCategorizedBooksJson(Map<String, dynamic> json) =>
[for (var books in json.values)
for (var book in books) Book.fromJson(book)];
(避免建立中间书籍列表)。
有了这个,您只需迭代外部地图的 values,并忽略键。 JSON 映射只是普通的 Dart Map
s,您可以访问键作为 .keys
(然后遍历它们而无需提前知道它们)并访问值作为 .values
(并完全忽略键)。
每个值都是一个图书列表,您可以使用现有的静态函数对其进行解析。
要包含该类型,您必须说明您希望如何记住该类型。最简单的就是将数据保留为地图:
var categoriedBooks = {for (var genre in json)
genre: Book.listFromJson(json[genre])
};
这将构建一个具有相同键(流派)的地图,但其中的值现在是 Book
s 的列表。