diff --git a/include/json/value.h b/include/json/value.h index 78e7546..c4169b4 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -395,6 +395,14 @@ Json::Value obj_value(Json::objectValue); // {} Value removeMember(const char* key); /// Same as removeMember(const char*) Value removeMember(const std::string& key); + /** \brief Remove the indexed array element. + + O(n) expensive operations. + Update 'removed' iff removed. + (This is a better pattern than removeMember().) + \return true iff removed (no exceptions) + */ + bool removeIndex(ArrayIndex i, Value* removed); /// Return true if the object has a member named key. bool isMember(const char* key) const; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 0a7fb85..7cc65bd 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1018,6 +1018,34 @@ Value Value::removeMember(const std::string& key) { return removeMember(key.c_str()); } +bool Value::removeIndex(ArrayIndex index, Value* removed) { + if (type_ != arrayValue) { + return false; + } +#ifdef JSON_VALUE_USE_INTERNAL_MAP + JSON_FAIL_MESSAGE("removeIndex is not implemented for ValueInternalArray."); + return false; +#else + CZString key(index); + ObjectValues::iterator it = value_.map_->find(key); + if (it == value_.map_->end()) { + return false; + } + *removed = it->second; + ArrayIndex oldSize = size(); + // shift left all items left, into the place of the "removed" + for (ArrayIndex i = index; i < (oldSize - 1); ++i){ + CZString key(i); + (*value_.map_)[key] = (*this)[i + 1]; + } + // erase the last one ("leftover") + CZString keyLast(oldSize - 1); + ObjectValues::iterator itLast = value_.map_->find(keyLast); + value_.map_->erase(itLast); + return true; +#endif +} + #ifdef JSON_USE_CPPTL Value Value::get(const CppTL::ConstString& key, const Value& defaultValue) const { diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 08ef66a..98fb8d0 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -198,6 +198,14 @@ JSONTEST_FIXTURE(ValueTest, objects) { object1_["some other id"] = "foo"; JSONTEST_ASSERT_EQUAL(Json::Value("foo"), object1_["some other id"]); + JSONTEST_ASSERT_EQUAL(Json::Value("foo"), object1_["some other id"]); + + // Remove. + Json::Value got; + got = object1_.removeMember("some other id"); + JSONTEST_ASSERT_EQUAL(Json::Value("foo"), got); + got = object1_.removeMember("some other id"); + JSONTEST_ASSERT_EQUAL(Json::nullValue, got); } JSONTEST_FIXTURE(ValueTest, arrays) { @@ -240,6 +248,10 @@ JSONTEST_FIXTURE(ValueTest, arrays) { array1_[2] = Json::Value(17); JSONTEST_ASSERT_EQUAL(Json::Value(), array1_[1]); JSONTEST_ASSERT_EQUAL(Json::Value(17), array1_[2]); + Json::Value got; + JSONTEST_ASSERT_EQUAL(true, array1_.removeIndex(2, &got)); + JSONTEST_ASSERT_EQUAL(Json::Value(17), got); + JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } JSONTEST_FIXTURE(ValueTest, null) {