Tôi hiện đang sử dụng Qt5.0 với thư viện QJson lõi để xử lý một số dữ liệu cho chương trình tôi đang phát triển.Làm thế nào để thay đổi giá trị QJsonObject trong phân cấp QJson mà không cần sử dụng bản sao?
Để thiết lập các cảnh cho câu hỏi này, tôi sẽ cung cấp cho bạn một số dữ liệu JSON minh họa vấn đề của tôi:
{
"CLOCKS": [
{
"ID": "clk",
"MAX": 2e+08,
"MIN": 1e+07,
"VALUE": "no_clock"
},
{
"ID": "memclk",
"MAX": 2e+08,
"MIN": 1e+07,
"VALUE": "memclk"
}
]
}
Ở đây chúng ta có một QJsonObject mẹ có chứa một chìa khóa duy nhất 'ĐỒNG HỒ'. Giá trị cho khóa này là QJsonArray của QJsonObjects chứa một số cặp khóa/giá trị chứa dữ liệu của tôi.
Nếu tôi muốn lấy QJsonObject với id 'CLK' Tôi hiện đang sử dụng mã như thế này:
// imagine m_data is my parent QJsonObject
QJsonArray clocks = m_data["CLOCKS"].toArray();
foreach (const QJsonValue & value, clocks) {
QJsonObject obj = value.toObject();
if (obj["ID"].toString() == "clk") {
return obj;
}
}
này hoạt động tốt và thư viện đã được tuyệt vời cho đến nay. Tuy nhiên, tôi đã bắt đầu chạy vào các vấn đề gần đây khi tôi muốn nhận được tài liệu tham khảo QJsonObject để sửa đổi thay vì bản sao. Vì vậy, câu hỏi của tôi là, cho các dữ liệu mẫu được cung cấp làm thế nào để tôi có được một tham chiếu QJsonObject để sửa đổi các cặp khóa/giá trị trong đối tượng dữ liệu đồng hồ mong muốn. Vấn đề hiển thị chính nó, IMO do thực tế là bạn có thể thu được QJsonValueRefs, là tham chiếu đến các giá trị mục nhập ... nhưng để thực sự truy cập dữ liệu bên trong này (nếu giá trị là một mảng/đối tượng khác), bạn phải chuyển đổi bằng cách sử dụng toArray Hàm(), toObject() vv Chức năng này chỉ trả về các bản sao chứ không phải các tham chiếu tạo ra một rào cản để lặp lại phân cấp đối tượng với các tham chiếu.
Cách duy nhất tôi tìm ra là tạo một bản sao toàn bộ "CLOCKS" QJsonArray, tìm đối tượng mà tôi muốn rồi xóa nó và chèn lại với dữ liệu đã thay đổi ... và cuối cùng gán toàn bộ mảng trở lại khóa "CLOCKS" trong đối tượng cha. Điều này dường như đủ rườm rà với tôi với tôi rằng tôi cảm thấy như tôi đang làm điều gì đó sai trái và phải có một cách tốt hơn.
Để hỗ trợ điều này đây là những gì mã của tôi trông như thế cho đến nay ... chỉ để thay đổi "VALUE" cho một trong những QJsonObjects đồng hồ:
QJsonArray resets = m_data.value(TAG_RESETS).toArray();
// get a copy of the QJsonObject
QJsonObject obj;
foreach (const QJsonValue & value, resets) {
QJsonObject o = value.toObject();
if (o.value(TAG_ID).toString() == id) {
obj = o;
break;
}
}
// modify the object
obj[TAG_VALUE] = "NEW VALUE";
// erase the old instance of the object
for (auto it = resets.begin(); it != resets.end(); ++it) {
QJsonObject obj = (*it).toObject();
if (obj.value(TAG_ID).toString() == id) {
resets.erase(it);
// assign the array copy which has the object deleted
m_data[TAG_RESETS] = resets;
break;
}
}
// add the modified QJsonObject
resets.append(obj);
// replace the original array with the array containing our modified object
m_data[TAG_RESETS] = resets;
Tôi biết điều này có thể được rút ngắn một chút nhưng nó vẫn có vẻ như có một cách tốt hơn để thay đổi một giá trị duy nhất trong một hệ thống phân cấp đối tượng QJson mà không cần phải nỗ lực hết sức này !!!
Tôi không tìm thấy bất kỳ cách nào. Nó thật kì lạ. Mô-đun QtScript cũ hỗ trợ điều này, bạn có thể sao chép QScriptValue. Sửa đổi đối tượng của bản sao gây ra sửa đổi tất cả các bản sao khác. QScriptObject nó không hoạt động theo cách đó. –