如何扁平化包含6种基础类型的多维嵌套QJsonValue结构?
扁平化多维嵌套QJsonValue的实现方法(支持全部6种基础类型)
需要实现一个工具方法,把包含object、array、bool、double、String、Null这6种基础类型的多维嵌套QJsonValue展开为扁平化的“键路径-值”结构,键路径用.分隔层级,所有值统一转为字符串格式,示例如下:
输入示例
{ "date": 1681693886, "online": true, "none": null, "list": { "arr": [ 60, 100, 100, 100, 100, 100 ], "multiArr": [ ["hi", "my", "name"], ["is", "unknown"], [{"first": 0}, {"last": 100}] ], "num": 60 } }
预期输出
key = "date", value = "1.68169e+09" key = "list.arr.0", value = "60" key = "list.arr.1", value = "100" key = "list.arr.2", value = "100" key = "list.arr.3", value = "100" key = "list.arr.4", value = "100" key = "list.arr.5", value = "100" key = "list.multiArr.0.0", value = "hi" key = "list.multiArr.0.1", value = "my" key = "list.multiArr.0.2", value = "name" key = "list.multiArr.1.0", value = "is" key = "list.multiArr.1.1", value = "unknown" key = "list.multiArr.2.0.first", value = "0" key = "list.multiArr.2.1.last", value = "100" key = "list.num", value = "60" key = "none", value = "null" key = "online", value = "true"
实现思路与代码
核心是通过递归遍历处理不同类型的QJsonValue,根据类型生成对应的键路径和字符串值:
#include <QJsonValue> #include <QJsonObject> #include <QJsonArray> #include <QMap> #include <QString> // 递归扁平化QJsonValue,结果存入map中,key为路径,value为字符串化的值 void flattenJson(const QJsonValue &value, const QString ¤tPath, QMap<QString, QString> &result) { switch (value.type()) { case QJsonValue::Null: result[currentPath] = "null"; break; case QJsonValue::Bool: result[currentPath] = value.toBool() ? "true" : "false"; break; case QJsonValue::Double: // 按照示例格式,保留5位小数的科学计数法 result[currentPath] = QString::number(value.toDouble(), 'e', 5); break; case QJsonValue::String: result[currentPath] = value.toString(); break; case QJsonValue::Object: { QJsonObject obj = value.toObject(); for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { QString newPath = currentPath.isEmpty() ? it.key() : currentPath + "." + it.key(); flattenJson(it.value(), newPath, result); } break; } case QJsonValue::Array: { QJsonArray arr = value.toArray(); for (int i = 0; i < arr.size(); ++i) { QString newPath = currentPath.isEmpty() ? QString::number(i) : currentPath + "." + QString::number(i); flattenJson(arr[i], newPath, result); } break; } default: // 处理未定义类型,可根据需求补充 result[currentPath] = "undefined"; break; } } // 对外接口,输入QJsonValue返回扁平化的键值对map QMap<QString, QString> flattenQJsonValue(const QJsonValue &root) { QMap<QString, QString> result; flattenJson(root, "", result); return result; }
使用示例
#include <QJsonDocument> #include <QDebug> int main() { // 解析输入的JSON字符串 QString jsonStr = R"( { "date": 1681693886, "online": true, "none": null, "list": { "arr": [60,100,100,100,100,100], "multiArr": [["hi","my","name"],["is","unknown"],[{"first":0},{"last":100}]], "num": 60 } } )"; QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8()); QMap<QString, QString> flatMap = flattenQJsonValue(doc.object()); // 按照示例格式输出 for (auto it = flatMap.constBegin(); it != flatMap.constEnd(); ++it) { qDebug().noquote() << QString("key = \"%1\",%2value = \"%3\"") .arg(it.key()) .arg(QString(25 - it.key().length(), ' ')) .arg(it.value()); } return 0; }
说明
- 针对double类型,使用科学计数法输出(保留5位小数),和示例格式一致;如果需要其他格式,可修改
QString::number的参数。 - 键路径的生成逻辑:根节点为空路径,object的键直接追加,array的索引转为字符串追加,层级用
.分隔。 - 所有值统一转为字符串,符合示例中的输出格式。
内容的提问来源于stack exchange,提问作者marc
相关产品推荐
相关产品推荐

