Итерировать с помощью итераторов на nlohmann::json? Ошибка: invalid_iterator

Продолжая мой предыдущий вопрос здесь, теперь я хочу вставить ключи и значения, представленные в приведенном ниже json, в std::vector<std::pair<std::string, std::vector<uint64_t>>> vec;

Ключами здесь являются следующие строки: 12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq , 12ashmTiFStQ8RGUpi1BTCinJakVyDKWjRL6SWhnbxbT

соответствующие им значения перечислены в списке:[20964,347474, 34747],[1992,1993,109096]

Это json, который является ответом на запрос.

         j =   {
                "12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq": [
                    20964,
                    347474,
                    347475
                ],
                "12ashmTiFStQ8RGUpi1BTCinJakVyDKWjRL6SWhnbxbT": [
                    1992,
                    1993,
                    109096  
                ]
        }

Чтобы сначала попробовать, я попытался вставить только ключ и значение первого элемента. Он работает правильно.

 std::vector<std::pair<std::string, std::vector<uint64_t>>> vec;
  auto key = j.begin().key();
  auto value = j.begin().value();
  vec.push_back(std::make_pair(key, value));

Теперь я пытаюсь таким образом вставить все ключевые значения в вектор

std::vector<std::pair<std::string, std::vector<uint64_t>>> vec;
  int i = 0;
  while ((j.begin() + i) != j.end()) {
    auto key = (j.begin() + i).key();
    auto value = (j.begin() + i).value();
    vec.push_back(std::make_pair(key, value));
    i++;
  }

Я получаю сообщение об ошибке:

 [json.exception.invalid_iterator.209]
cannot use offsets with object iterators

Может кто-нибудь, пожалуйста, каков правильный способ сделать это?

Похоже, что итераторы json не имеют произвольного доступа. Вместо увеличения смещения, как насчет for(auto it = j.begin(); it != j.end(); ++it)?

Nathan Pierson 25.11.2022 19:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
122
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы слишком усложняете это. Вы можете перебирать объект json так же, как и любой другой контейнер, используя цикл for:

#include "nlohmann/json.hpp"
#include <iostream>

int main()
{
    nlohmann::json j = nlohmann::json::parse(R"({
                "12CUDzb3oe8RBQ4tYGqsuPsCbsVE4KWfktXRihXf8Ggq": [
                    20964,
                    347474,
                    347475
                ],
                "12ashmTiFStQ8RGUpi1BTCinJakVyDKWjRL6SWhnbxbT": [
                    1992,
                    1993,
                    109096  
                ]
        })");
    std::vector<std::pair<std::string, std::vector<uint64_t>>> vec;
    for (auto it = j.begin(); it != j.end(); ++it)    
    {
        vec.emplace_back(it.key(), it.value());
    }
    for (auto& it : vec)
    {
        std::cout << it.first << ": ";
        for (auto& value : it.second)
        {
            std::cout << value << ", ";
        }
        std::cout << "\n";
    }
}

Если вас не волнует порядок элементов (ключи JSON в любом случае неупорядочены, а nlohmann не сохраняет порядок по умолчанию), то вы можете сделать это в одну строку:

std::map<std::string, std::vector<uint64_t>> vec = j;

Ого... it.value() вместо моего слишком сложного решения. Великолепно! +1 и удаление моего ответа.

Ted Lyngmo 25.11.2022 19:22

@TedLyngmo да, библиотека делает все за вас, практически никогда не нужно ничего делать с векторами напрямую

Alan Birtles 25.11.2022 19:27

Да, я использовал его, но только 1-2 дня здесь и там с перерывом в несколько лет, поэтому я еще не освоился с ним. Несколько лет назад я внимательно изучил код библиотеки и помню, как был впечатлен тем, насколько хорошо он написан, как мне казалось.

Ted Lyngmo 25.11.2022 19:33

Другие вопросы по теме