Построить список QVariant из неупорядоченных данных

У меня есть этот набор данных:

[ step:-1, name:"BaseName1",  value:v1 ]
[ step:-1, name:"BaseName2",  value:v2 ]
[ step:2,  name:"ParamName3", value:v3 ]
[ step:2,  name:"ParamName4", value:v4 ]
[ step:0,  name:"ParamName5", value:v5 ]
[ step:0,  name:"ParamName6", value:v6 ]
[ step:1,  name:"ParamName7", value:v7 ]
[ step:1,  name:"ParamName8", value:v8 ]

Что я хотел бы преобразовать в QVariant, например:

[
"BaseName1": v1,
"BaseName2": v2,
"steps": [{
"ParamName5": v5,
"ParamName6": v6
}, {
"ParamName7": v7,
"ParamName8": v8
}, {
"ParamName3": v3,
"ParamName4": v4
}
]
]

Я подумал, что это должно быть так:

QVariantMap params;
params["Base_param_1"] = value;
params["Base_param_2"] = value2;
params["steps"] = QVariantList();

Но для массива мне нужно упорядочить данные; что означает, что я должен вставить шаг 0 в params["steps"] до шаги 1 и 3 (и шаг 2 должен быть пустым).
Кроме того, сортировка входных данных не вариант.

Я попытался реализовать это с помощью следующего кода:

struct Params{
QString name;
QVariant value;
int step;/* -1 for base param */
};
QList<Params> _params = (...);

QVariantMap v_settings;
QVariantList v_steps;

for(int i=0; i<_params.size(); i++){
const Param &param = _params[i];

if( param.index == -1 ){
v_settings.insert(param.name, param.value);
}
else {
// if list too small, append empties to the list until it exists
while( v_steps.size() < param.index ){
QVariantMap map;
v_steps.append(map);
}

v_steps.at(param.index).toMap().insert(param.name, param.value);
}
}
v_settings.insert("steps", v_steps);

Но в какой-то момент код завершается с ошибкой индекса за пределами этой строки:

v_steps.at(param.index).toMap().insert(param.name, param.value);

Поэтому я думаю, что мой цикл «заполнить пустыми картами» как-то не удался
Как мне здесь быть?

1

Решение

В вашем коде есть несколько проблем.

Проблема «Индекс выходит за границы» возникает из-за того, что вы не добавили достаточно объектов в свой список. Ты должен написать

while( v_steps.size() <= param.index ) {

то есть заменить < с <=, Это обеспечит, например, 6 элементов будут содержаться в массиве до доступа к 5-му элементу (количество элементов начинается с 0, помните?)

Еще одна проблема в toMap().insert, toMap() возвращается QMap по значению, а не по ссылке. Так что нет смысла звонить insert на нем, потому что это просто временное значение, которое не было присвоено ни одной переменной. Он будет уничтожен сразу после insert заканчивается, и никакие изменения не будут сохранены.

Я предлагаю вам использовать QVector<QVariantMap> v_steps хранить ваши данные. QVector лучше, чем QList в этом случае, потому что это легко resize() Это. Вставка может быть выполнена с использованием следующего кода:

v_steps[param.index].insert(param.name, param.value);

Затем вам нужно преобразовать его в QVariantList:

QVariantList v_steps_real;
foreach(QVariantMap map, v_steps) {
v_steps_real << map;
}
v_settings.insert("steps", v_steps_real);

Обратите внимание, что вы можете использовать [] оператор вместо insert() чтобы вставить значения в карту:

map["key"] = value;
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]