Skip to content

Commit bcb19ff

Browse files
authored
Implement a JSON::erase_if method for arrays (#1835)
Fixes: #1834 Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent f2a1c96 commit bcb19ff

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/core/json/include/sourcemeta/core/json_value.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,23 @@ class SOURCEMETA_CORE_JSON_EXPORT JSON {
14431443
auto erase(typename Array::const_iterator first,
14441444
typename Array::const_iterator last) -> typename Array::iterator;
14451445

1446+
/// This method deletes a set of array elements given a predicate. For
1447+
/// example:
1448+
///
1449+
/// ```cpp
1450+
/// #include <sourcemeta/core/json.h>
1451+
/// #include <cassert>
1452+
///
1453+
/// sourcemeta::core::JSON array =
1454+
/// sourcemeta::core::parse_json("[ 1, 2, 3 ]");
1455+
/// array.erase_if(array,
1456+
/// [](const auto &item) { return item.to_integer() % 2 == 0; });
1457+
/// assert(array.size(), 2);
1458+
/// assert(array.at(0), 1);
1459+
/// assert(array.at(1), 3);
1460+
/// ```
1461+
auto erase_if(const std::function<bool(const JSON &)> &predicate) -> void;
1462+
14461463
/// This method deletes all members of an object or all elements of an array,
14471464
/// leaving them empty. For example:
14481465
///

src/core/json/json_value.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,12 @@ auto JSON::erase(typename JSON::Array::const_iterator first,
852852
return this->data_array.data.erase(first, last);
853853
}
854854

855+
auto JSON::erase_if(const std::function<bool(const JSON &)> &predicate)
856+
-> void {
857+
assert(this->is_array());
858+
std::erase_if(this->data_array.data, predicate);
859+
}
860+
855861
auto JSON::clear() -> void {
856862
if (this->is_object()) {
857863
this->data_object.data.clear();

test/json/json_array_test.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,3 +534,45 @@ TEST(JSON_array, sort_object_items) {
534534

535535
EXPECT_EQ(document, expected);
536536
}
537+
538+
TEST(JSON_array, erase_if_some) {
539+
auto document = sourcemeta::core::parse_json(R"JSON([
540+
1, 2, 3, 4, 5
541+
])JSON");
542+
543+
document.erase_if([](const auto &item) {
544+
return item.is_integer() && item.to_integer() % 2 == 0;
545+
});
546+
547+
const auto expected = sourcemeta::core::parse_json(R"JSON([
548+
1, 3, 5
549+
])JSON");
550+
551+
EXPECT_EQ(document, expected);
552+
}
553+
554+
TEST(JSON_array, erase_if_none) {
555+
auto document = sourcemeta::core::parse_json(R"JSON([
556+
1, 2, 3, 4, 5
557+
])JSON");
558+
559+
document.erase_if([](const auto &item) { return item.is_boolean(); });
560+
561+
const auto expected = sourcemeta::core::parse_json(R"JSON([
562+
1, 2, 3, 4, 5
563+
])JSON");
564+
565+
EXPECT_EQ(document, expected);
566+
}
567+
568+
TEST(JSON_array, erase_if_all) {
569+
auto document = sourcemeta::core::parse_json(R"JSON([
570+
1, 2, 3, 4, 5
571+
])JSON");
572+
573+
document.erase_if([](const auto &item) { return item.is_integer(); });
574+
575+
const auto expected = sourcemeta::core::parse_json(R"JSON([])JSON");
576+
577+
EXPECT_EQ(document, expected);
578+
}

0 commit comments

Comments
 (0)