漯河市网站建设_网站建设公司_页面加载速度_seo优化
2026/1/9 11:43:25 网站建设 项目流程

一 概述

对于纯数组嵌套的JSON数据,QJsonArray完全支持嵌套查找,可以通过多层索引逐层访问。由于没有对象键名,查找完全依赖于数组索引。

二 纯数组嵌套JSON示例


[
[
["a", "b", "c"],
["d", "e", "f"]
],
[
[100, 200, 300],
[400, 500, 600]
],
[
[true, false],
[null, "text"]
]
]

三 基本嵌套查找方法

1 直接索引访问


#include <QJsonDocument>
#include <QJsonArray>

// 解析纯数组JSON
QJsonDocument doc = QJsonDocument::fromJson("[ [[1,2],[3,4]], [[5,6],[7,8]] ]");
QJsonArray rootArray = doc.array();

// 逐层索引访问
if (rootArray.size() > 0 && rootArray[0].isArray()) {
QJsonArray secondLevel = rootArray[0].toArray();
if (secondLevel.size() > 1 && secondLevel[1].isArray()) {
QJsonArray thirdLevel = secondLevel[1].toArray();
if (thirdLevel.size() > 0) {
// 访问 [0][1][0] 的值
QJsonValue value = thirdLevel[0];
qDebug() << "值:" << value.toInt(); // 输出: 3
}
}
}

2 使用辅助函数进行路径查找


/**
* 通过整数索引路径查找纯数组中的值
* @param array 根数组
* @param indexPath 索引路径,如 [0,1,0] 表示 array[0][1][0]
* @return 找到的值,未找到返回 QJsonValue::Undefined
*/
QJsonValue findInNestedArray(const QJsonArray& array, const QVector<int>& indexPath) {
QJsonValue current = array;

for (int index : indexPath) {
if (current.isArray()) {
QJsonArray currentArray = current.toArray();
if (index >= 0 && index < currentArray.size()) {
current = currentArray.at(index);
} else {
return QJsonValue::Undefined; // 索引越界
}
} else {
return QJsonValue::Undefined; // 路径中间不是数组
}
}

return current;
}

// 使用示例
QVector<int> path = {0, 1, 0}; // 查找 [0][1][0]
QJsonValue result = findInNestedArray(rootArray, path);
if (!result.isUndefined()) {
qDebug() << "找到的值:" << result.toInt();
}

3 使用字符串路径(点分隔索引)


/**
* 使用点分隔的字符串路径查找,如 "0.1.0"
*/
QJsonValue findInArrayByStringPath(const QJsonArray& array, const QString& path) {
QStringList indexStrings = path.split('.');
QJsonValue current = array;

for (const QString& indexStr : indexStrings) {
bool ok;
int index = indexStr.toInt(&ok);

if (!ok || index < 0) {
return QJsonValue::Undefined; // 无效的索引格式
}

if (current.isArray()) {
QJsonArray currentArray = current.toArray();
if (index < currentArray.size()) {
current = currentArray.at(index);
} else {
return QJsonValue::Undefined; // 索引越界
}
} else {
return QJsonValue::Undefined; // 中间不是数组
}
}

return current;
}

// 使用示例
QJsonValue value = findInArrayByStringPath(rootArray, "0.1.0");
if (!value.isUndefined()) {
qDebug() << "值:" << value.toString(); // 如果是字符串数组
}

四 实际应用场景

1 多维矩阵/表格数据


// 表示3x3矩阵
QString jsonStr = R"([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])";

QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());
QJsonArray matrix = doc.array();

// 获取第2行第3列(索引 [1][2])
QJsonValue element = findInArrayByStringPath(matrix, "1.2");
if (!element.isUndefined()) {
qDebug() << "矩阵[1][2] =" << element.toInt(); // 输出: 6
}

2 三维坐标数据


// 多个三维坐标点
QString coordsJson = R"([
[[10, 20, 30], [40, 50, 60]],
[[70, 80, 90], [100, 110, 120]]
])";

QJsonArray coordsArray = QJsonDocument::fromJson(coordsJson.toUtf8()).array();

// 获取第二个点的Z坐标: [1][0][2]
QJsonValue zCoord = findInArrayByStringPath(coordsArray, "1.0.2");
if (!zCoord.isUndefined()) {
qDebug() << "Z坐标:" << zCoord.toInt(); // 输出: 90
}

3 树形结构(使用数组表示)


// 使用数组表示的树形结构,每个节点是一个数组 [value, [children...]]
QString treeJson = R"([
"Root", [
["A", [
["A1", []],
["A2", []]
]],
["B", [
["B1", []],
["B2", [
["B2a", []]
]]
]]
]
])";

QJsonArray tree = QJsonDocument::fromJson(treeJson.toUtf8()).array();

// 遍历树的深度优先搜索
void traverseTree(const QJsonArray& node, int depth = 0) {
if (node.size() >= 1) {
QString indent(depth * 2, ' ');
qDebug() << indent << node[0].toString();

if (node.size() >= 2 && node[1].isArray()) {
QJsonArray children = node[1].toArray();
for (const QJsonValue& child : children) {
if (child.isArray()) {
traverseTree(child.toArray(), depth + 1);
}
}
}
}
}

traverseTree(tree);

五 通用嵌套数组操作函数

1 检查路径是否有效


bool isValidArrayPath(const QJsonArray& array, const QVector<int>& path) {
const QJsonArray* current = &array;

for (int i = 0; i < path.size(); i++) {
int index = path[i];

if (index < 0 || index >= current->size()) {
return false; // 索引越界
}

// 如果是最后一个索引,不需要检查类型
if (i == path.size() - 1) {
return true;
}

// 中间路径必须是数组
QJsonValue nextValue = current->at(index);
if (!nextValue.isArray()) {
return false;
}

current = &nextValue.toArray();
}

return true;
}
```

2 设置嵌套数组的值


/**
* 设置嵌套数组中指定路径的值
* 如果路径不存在,会自动创建中间数组(填充null值)
*/
bool setNestedArrayValue(QJsonArray& array, const QVector<int>& path, const QJsonValue& value) {
if (path.isEmpty()) {
return false;
}

QJsonArray* current = &array;

// 处理除最后一个索引外的所有路径
for (int i = 0; i < path.size() - 1; i++) {
int index = path[i];

// 确保数组足够大
while (current->size() <= index) {
current->append(QJsonValue::Null);
}

// 如果当前位置不是数组,用数组替换
if (!current->at(index).isArray()) {
(*current)[index] = QJsonArray();
}

QJsonValue nextValue = current->at(index);
current = const_cast<QJsonArray*>(&nextValue.toArray());
}

// 设置最后一个索引的值
int lastIndex = path.last();

// 确保数组足够大
while (current->size() <= lastIndex) {
current->append(QJsonValue::Null);
}

(*current)[lastIndex] = value;
return true;
}

// 使用示例
QJsonArray data;
QVector<int> path = {0, 1, 2};
setNestedArrayValue(data, path, "Hello");
// 现在 data[0][1][2] = "Hello",自动创建了中间数组

3 查找所有叶节点


/**
* 获取纯数组结构中的所有叶节点(非数组的值)
*/
QVector<QJsonValue> getAllLeaves(const QJsonArray& array) {
QVector<QJsonValue> leaves;

for (const QJsonValue& value : array) {
if (value.isArray()) {
leaves.append(getAllLeaves(value.toArray()));
} else {
leaves.append(value);
}
}

return leaves;
}

// 使用示例
QVector<QJsonValue> leaves = getAllLeaves(rootArray);
for (const QJsonValue& leaf : leaves) {
qDebug() << "叶节点:" << leaf.toString();
}

六 性能优化建议

1 批量操作减少递归深度


// 对于大量数据的查找,考虑使用迭代而非递归
QJsonValue iterativeFind(const QJsonArray& array, const QVector<int>& path) {
const QJsonValue* current = nullptr;
const QJsonArray* currentArray = &array;

for (int i = 0; i < path.size(); i++) {
int index = path[i];

if (index < 0 || index >= currentArray->size()) {
return QJsonValue::Undefined;
}

current = &currentArray->at(index);

// 如果是最后一个索引,直接返回
if (i == path.size() - 1) {
return *current;
}

// 否则继续深入
if (current->isArray()) {
currentArray = &current->toArray();
} else {
return QJsonValue::Undefined;
}
}

return QJsonValue::Undefined;
}

2 缓存常用路径结果


class CachedArrayLookup {
private:
QJsonArray data;
QHash<QString, QJsonValue> cache; // 路径 -> 值 的缓存

public:
CachedArrayLookup(const QJsonArray& array) : data(array) {}

QJsonValue get(const QString& path) {
if (cache.contains(path)) {
return cache[path];
}

QJsonValue result = findInArrayByStringPath(data, path);
cache[path] = result;
return result;
}

void clearCache() {
cache.clear();
}
};

六 总结

对于纯数组嵌套的JSON,QJsonArray完全支持嵌套查找,主要通过:

1 整数索引路径逐层访问嵌套数组。
2 辅助函数简化复杂路径的查找操作。
3 类型检查确保每层都是数组类型。
4 边界检查防止索引越界。

虽然纯数组结构没有对象键名直观,但通过良好的索引管理和辅助工具,完全可以高效地进行嵌套查找和操作。在处理这类数据时,建议:

1 封装查找函数以提高代码复用性。
2 添加充分的错误检查和日志。
3 对于复杂业务逻辑,考虑添加索引映射层。
4 注意性能,避免不必要的深层递归。

纯数组嵌套在某些场景(如数学计算、游戏地图、多维数据)中非常有用,QJsonArray提供了足够的基础功能来处理这些需求。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询