简体   繁体   中英

How to remove or erase a "key":"value" pair in a Json::Value object using "key"?

I am working in C++ language, visual studio 2022, and using jsoncpp library for working with Json.

To Give you an Idea, here is an example of Json data I am working with

[ 
    { 
        "name":"Regina Eagle",
        "job":"Biologist",
        "salary":"728148120",
        "email":"Regina_Eagle6155@y96lx.store",
        "city":"Nashville"
    },
    { 
        "name":"Julius Baker",
        "job":"Fabricator",
        "salary":"299380360",
        "email":"Julius_Baker9507@voylg.center",
        "city":"Las Vegas"
    },
    { 
        "name":"Rocco Sawyer",
        "job":"Chef Manager",
        "salary":"223764496",
        "email":"Rocco_Sawyer4620@qu9ml.club",
        "city":"San Francisco"
    },
    { 
        "name":"Chad Murray",
        "job":"Project Manager",
        "salary":"43031808",
        "email":"Chad_Murray6940@jcf8v.store",
        "city":"Bridgeport"
    },
    { 
        "name":"Rocco Parker",
        "job":"Lecturer",
        "salary":"322089172",
        "email":"Rocco_Parker202@ag5wi.solutions",
        "city":"Indianapolis"
    }
]

It's a Json array of objects (with key:value pairs). I have a set of column heads for eg: {"name","job","salary"}, and I want to sort the json data in a way that each object will have only columns that are in the given set.

This is my approach:

Store json data in a Json::Value object (let us say records).

Iterate through records (as it is an array).

Creating another loop to Iterate through object stored at each index.

Extract the key of the key:value pair and check if it's present in the set or not.

If it's present then continue, else if it isn't then remove that key:value entry from there.

This way we can delete unwanted column while looping through the object.

Here, is the code snippet:

set<string> col {"name","job","salary"};
Json::Value records = [ 
    { 
        "name":"Regina Eagle",
        "job":"Biologist",
        "salary":"728148120",
        "email":"Regina_Eagle6155@y96lx.store",
        "city":"Nashville"
    },
    { 
        "name":"Julius Baker",
        "job":"Fabricator",
        "salary":"299380360",
        "email":"Julius_Baker9507@voylg.center",
        "city":"Las Vegas"
    },
    { 
        "name":"Rocco Sawyer",
        "job":"Chef Manager",
        "salary":"223764496",
        "email":"Rocco_Sawyer4620@qu9ml.club",
        "city":"San Francisco"
    },
    { 
        "name":"Chad Murray",
        "job":"Project Manager",
        "salary":"43031808",
        "email":"Chad_Murray6940@jcf8v.store",
        "city":"Bridgeport"
    },
    { 
        "name":"Rocco Parker",
        "job":"Lecturer",
        "salary":"322089172",
        "email":"Rocco_Parker202@ag5wi.solutions",
        "city":"Indianapolis"
    }
];

for (int i = 0; i<records.size(); i++)
{
  for (auto j = records[i].begin(); j != records[i].end(); j++)
    {
      string key = j.key().asString();
      if (col.find(key) != col.end())
        {
          continue;
        }
      else
        {
          records[i].removeMember(key);
        }
    }
}

It works fine until the 'removeMember' function get to run, and throws an error saying can't increment the value of iterator.

Expression: cannot increment value-initialized map/set iterator

Am I doing something wrong?

Or there is another/better way of doing this?

Please advice.

Don't remove or add elements in a container you're currently iterating.

The JSON objects are stored in a std::map and removeMember calls std::map::erase . It invalidates the current iterator and it can't be incremented anymore. j++ causes the error.

One approach is to first only store the keys of properties you want to delete, and then to delete the properties in a separate loop.

set<string> col {"name","job","salary"};
Json::Value records = [ 
    { 
        "name":"Regina Eagle",
        "job":"Biologist",
        "salary":"728148120",
        "email":"Regina_Eagle6155@y96lx.store",
        "city":"Nashville"
    },
    { 
        "name":"Julius Baker",
        "job":"Fabricator",
        "salary":"299380360",
        "email":"Julius_Baker9507@voylg.center",
        "city":"Las Vegas"
    },
    { 
        "name":"Rocco Sawyer",
        "job":"Chef Manager",
        "salary":"223764496",
        "email":"Rocco_Sawyer4620@qu9ml.club",
        "city":"San Francisco"
    },
    { 
        "name":"Chad Murray",
        "job":"Project Manager",
        "salary":"43031808",
        "email":"Chad_Murray6940@jcf8v.store",
        "city":"Bridgeport"
    },
    { 
        "name":"Rocco Parker",
        "job":"Lecturer",
        "salary":"322089172",
        "email":"Rocco_Parker202@ag5wi.solutions",
        "city":"Indianapolis"
    }
];

for (int i = 0; i<records.size(); i++)
{
  std::vector<std::string> toRemove;
  for (auto j = records[i].begin(); j != records[i].end(); j++)
    {
      string key = j.key().asString();
      if (col.find(key) != col.end())
        {
          continue;
        }
      else
        {
          // records[i].removeMember(key);
          toRemove.push_back(key);
        }
    }
  for (const auto &key : toRemove)
    {
      records[i].removeMember(key);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM