はじめに
とある事情でFlutterのJSONをフラットにする必要があったが、探してもこれと言うものが見つからず….
自作してみたので、そのコードを公開します!
実装コード
注: リストは key.0: value0, key.1: value1 のように表示されます。
Note: Lists are displayed as `key.0: value0, key.1: value1`, and so on.
/// Convert nested json to flat json
Map<String, dynamic> convert({required Map<String, dynamic> map, String? parentKey}) {
final Map<String, dynamic> newMap = {};
for(var MapEntry(key: key, value: value) in map.entries){
final newkey = parentKey != null ? "$parentKey.$key" : key;
if(value is List){
value = value.asMap().map((key, value) => MapEntry("$key", value));
}
if(value is Map){
final convertMap = convert(map: value as Map<String, dynamic>, parentKey: newkey);
newMap.addAll(convertMap);
}else{
newMap[newkey] = value;
}
}
return newMap;
}テスト
テスト用JSONは、https://json.org/example.htmlから取得
ネストしたJSON
IN
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": ["GML", "XML"]
},
"GlossSee": "markup"
}
}
}
}
}OUT
{
"glossary.title": "example glossary",
"glossary.GlossDiv.title": "S",
"glossary.GlossDiv.GlossList.GlossEntry.ID": "SGML",
"glossary.GlossDiv.GlossList.GlossEntry.SortAs": "SGML",
"glossary.GlossDiv.GlossList.GlossEntry.GlossTerm": "Standard Generalized Markup Language",
"glossary.GlossDiv.GlossList.GlossEntry.Acronym": "SGML",
"glossary.GlossDiv.GlossList.GlossEntry.Abbrev": "ISO 8879:1986",
"glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para": "A meta-markup language, used to create markup languages such as DocBook.",
"glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso.0": "GML",
"glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso.1": "XML",
"glossary.GlossDiv.GlossList.GlossEntry.GlossSee": "markup"
}nullありJSON
IN
{"menu": {
"header": "SVG Viewer",
"items": [
{"id": "Open"},
{"id": "OpenNew", "label": "Open New"},
null,
{"id": "ZoomIn", "label": "Zoom In"},
{"id": "ZoomOut", "label": "Zoom Out"},
{"id": "OriginalView", "label": "Original View"},
null,
{"id": "Quality"},
{"id": "Pause"},
{"id": "Mute"},
null,
{"id": "Find", "label": "Find..."},
{"id": "FindAgain", "label": "Find Again"},
{"id": "Copy"},
{"id": "CopyAgain", "label": "Copy Again"},
{"id": "CopySVG", "label": "Copy SVG"},
{"id": "ViewSVG", "label": "View SVG"},
{"id": "ViewSource", "label": "View Source"},
{"id": "SaveAs", "label": "Save As"},
null,
{"id": "Help"},
{"id": "About", "label": "About Adobe CVG Viewer..."}
]
}}OUT
{
"menu.header": "SVG Viewer",
"menu.items.0.id": "Open",
"menu.items.1.id": "OpenNew",
"menu.items.1.label": "Open New",
"menu.items.2": null,
"menu.items.3.id": "ZoomIn",
"menu.items.3.label": "Zoom In",
"menu.items.4.id": "ZoomOut",
"menu.items.4.label": "Zoom Out",
"menu.items.5.id": "OriginalView",
"menu.items.5.label": "Original View",
"menu.items.6": null,
"menu.items.7.id": "Quality",
"menu.items.8.id": "Pause",
"menu.items.9.id": "Mute",
"menu.items.10": null,
"menu.items.11.id": "Find",
"menu.items.11.label": "Find...",
"menu.items.12.id": "FindAgain",
"menu.items.12.label": "Find Again",
"menu.items.13.id": "Copy",
"menu.items.14.id": "CopyAgain",
"menu.items.14.label": "Copy Again",
"menu.items.15.id": "CopySVG",
"menu.items.15.label": "Copy SVG",
"menu.items.16.id": "ViewSVG",
"menu.items.16.label": "View SVG",
"menu.items.17.id": "ViewSource",
"menu.items.17.label": "View Source",
"menu.items.18.id": "SaveAs",
"menu.items.18.label": "Save As",
"menu.items.19": null,
"menu.items.20.id": "Help",
"menu.items.21.id": "About",
"menu.items.21.label": "About Adobe CVG Viewer..."
}悪くなさそう!
補足)コンソールでdart run で動かすサンプル
assets/test.jsonにjsonを用意し、以下のコードを、dart run test.dart
import 'dart:convert';
import 'dart:io';
/// Convert nested json to flat json
Map<String, dynamic> convert({required Map<String, dynamic> map, String? parentKey}) {
final Map<String, dynamic> newMap = {};
for(var MapEntry(key: key, value: value) in map.entries){
final newkey = parentKey != null ? "$parentKey.$key" : key;
if(value is List){
value = value.asMap().map((key, value) => MapEntry("$key", value));
}
if(value is Map){
final convertMap = convert(map: value as Map<String, dynamic>, parentKey: newkey);
newMap.addAll(convertMap);
}else{
newMap[newkey] = value;
}
}
return newMap;
}
/// Read json file and return as Map
Future<Map<String, dynamic>> readJsonFile(String filePath) async {
final input = await File(filePath).readAsString();
final map = jsonDecode(input);
return map;
}
/// Print json in a pretty format
void prityPrintJson(Map<String, dynamic> map){
JsonEncoder encoder = new JsonEncoder.withIndent(' ');
String prettyJson = encoder.convert(map);
print(prettyJson);
}
main() async{
final json = await readJsonFile('assets/test.json');
prityPrintJson(json);
final convertedJson = convert(map: json);
prityPrintJson(convertedJson);
}


コメント