如何解析嵌套的 JSON 字典(地图)

Posted

技术标签:

【中文标题】如何解析嵌套的 JSON 字典(地图)【英文标题】:How to parse a nested JSON dictionary (map) 【发布时间】:2020-12-08 22:27:07 【问题描述】:

我正在尝试将与 Swift 程序兼容的 JSON 代码读入 Flutter 应用程序。结构是这样的:


  "tagDict" : 
    "abc" : 
      "helpHdr" : "short text1",
      "helpText" : "long text1"
    ,
    "def" : 
      "helpHdr" : "short text2",
      "helpText" : "long text2"
    
  

这会在 Swift 中创建一个字典,并在 Dart 中创建一个 key : helpHdr, helpText 类型的映射。基于此的变量应该启用 label = myVariable[tag].helpHdr,或者保留示例 label = myVariable["abc"].helpHdr 应该将“short text1”分配给标签

为了解析嵌套数组,我正在使用它,但是,不知道如何将它转移到这样的嵌套映射中。

class MyClass 
  List<MySubClass> myArray;
  MyClass(
    this.myArray,
  );

  factory MyClass.fromJson(Map<String, dynamic> parsedJson)
    var list = parsedJson['myArray'] as List;
    List<MySubClass> listObject = list.map((i) => MySubClass.fromJson(i)).toList();
    return new MyClass(
      myArray: listObject,
    );
  


class MySubClass 
  int id;
  String text1;
  String text2;
  MySubClass(
    this.id,
    this.text1,
    this.text2,
  );

  factory MySubClass.fromJson(Map<String, dynamic> parsedJson)
    return new MySubClass(
      id: parsedJson['id'],
      text1: parsedJson['text1'],
      text2: parsedJson['text2'],
    );
  

【问题讨论】:

你已经拥有的有什么问题?为什么需要嵌套地图?但是如果你真的需要一个嵌套的地图,你可以使用与 subclass.fromJson 做同样事情但返回地图的方法来代替使用子类。 试试这个。您可以定义类的外观,并让构建运行器处理其他所有事情。 flutter.dev/docs/development/data-and-backend/… 【参考方案1】:

根据 Tipu 的回答,我想出了以下代码来创建预期的字典(或 Dart 中的映射 - 为什么他们不能坚持使用标准术语,如数组等?!)

class TaskTags 
  var tagDict = Map<String, TaskTag>();
  TaskTags(
    this.tagDict,
  );

  factory TaskTags.fromJson(Map<String, dynamic> json)
    var innerMap = json['tagDict'];
    var tagMap = Map<String, TaskTag>();
    innerMap.forEach((key, value) 
      tagMap.addAll(key: TaskTag.fromJson(value));
    );
    return new TaskTags(
      tagDict: tagMap,
    );
  


class TaskTag 
  String helpHdr;
  String helpText;
  TaskTag(
    this.helpHdr,
    this.helpText,
);

  factory TaskTag.fromJson(Map<String, dynamic> json)
    return new TaskTag(
      helpHdr: json['helpHdr'],
      helpText: json['helpText'],
    );
  

这将创建以下地图

"abc“ : helpHdr: "short text1", helpText: "long text1", "def“ : helpHdr: "short text2", helpText: "long text2"

【讨论】:

【参考方案2】:
class TagRes 
TagDict tagDict;

TagRes(this.tagDict);

TagRes.fromJson(Map<String, dynamic> json) 
tagDict =
    json['tagDict'] != null ? new TagDict.fromJson(json['tagDict']) : null;


Map<String, dynamic> toJson() 
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.tagDict != null) 
  data['tagDict'] = this.tagDict.toJson();

return data;

 

class TagDict 
 Abc abc;
Abc def;

TagDict(this.abc, this.def);

 TagDict.fromJson(Map<String, dynamic> json) 
  abc = json['abc'] != null ? new Abc.fromJson(json['abc']) : null;
  def = json['def'] != null ? new Abc.fromJson(json['def']) : null;
 

 Map<String, dynamic> toJson() 
  final Map<String, dynamic> data = new Map<String, dynamic>();
  if (this.abc != null) 
  data['abc'] = this.abc.toJson();
  
   if (this.def != null) 
  data['def'] = this.def.toJson();
 
  return data;
 
 

class Abc 
String helpHdr;
  String helpText;

  Abc(this.helpHdr, this.helpText);

  Abc.fromJson(Map<String, dynamic> json) 
   helpHdr = json['helpHdr'];
   helpText = json['helpText'];
 

 Map<String, dynamic> toJson() 
final Map<String, dynamic> data = new Map<String, dynamic>();
data['helpHdr'] = this.helpHdr;
data['helpText'] = this.helpText;
return data;
 

【讨论】:

【参考方案3】:

如果我是正确的,您想将您的 json 解析为 Data 类对象。如果是对的,那么你可以试试这个

void main() 
  List<MyClass> myClassList = new List<MyClass>();
  Map map = 
    "tagDict": 
      "abc": "helpHdr": "short text1", "helpText": "long text1",
      "def": "helpHdr": "short text2", "helpText": "long text2"
    
  ;

  map['tagDict'].forEach((key, value) 
    value['id'] = key;
    myClassList.add(MyClass.fromJson(value));
  );

  myClassList.forEach((myClass) 
    print(myClass.id);
    print(myClass.helpHdr);
    print(myClass.helpText);
    print("--------------------\n");
  );


class MyClass 
  String id;
  String helpHdr;
  String helpText;

  MyClass(this.id, this.helpHdr, this.helpText);

  MyClass.fromJson(Map<String, dynamic> json) 
    id = json['id'];
    helpHdr = json['helpHdr'];
    helpText = json['helpText'];
  

  Map<String, dynamic> toJson() 
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['helpHdr'] = this.helpHdr;
    data['helpText'] = this.helpText;
    return data;
  

这是输出:

abc
short text1
long text1
--------------------

def
short text2
long text2
--------------------

【讨论】:

不确定。需要跑去开会,所以稍后会更详细地检查。但是,我想要一本我不必搜索 where id = "abc" 然后打印相关的 helpHdr 而是使用 myClassList["abc"].helpHdr 的字典。 虽然这没有提供预期的数据结构,但它为我提供了解决方案的构建块。谢谢!

以上是关于如何解析嵌套的 JSON 字典(地图)的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套的字典和列表解析 JSON

如何解析嵌套的json?迅速

使用 Newtonsoft 解析带有嵌套和变量字典的 Json [重复]

使用jsonpath解析多层嵌套的json响应信息

JSON 和嵌套的 NSDictionary

从 JSON 字符串到字典的简单解析器