Rapidjson: Sorting using rapidjson

Created on 22 Jan 2016  路  3Comments  路  Source: Tencent/rapidjson

I have an array of JSON objects that I want to sort. I know that C++ has a sort function. How would I be able to use that to sort my array? Is there a way to convert between Arrays in rapidjson and arrays in c++?

Most helpful comment

I tried on clang. its C++03 version of std::sort seems require copy constructor, which is not supported by Value.

However, in C++11 std::sort only requires the types to be MoveAssignable and MoveConstructible.

And it works with RAPIDJSON_HAS_CXX11_RVALUE_REFS=1

struct ValueIntComparer {
    bool operator()(const Value& lhs, const Value& rhs) const {
        return lhs.GetInt() < rhs.GetInt();
    }
};

#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, Sorting) {
    Value::AllocatorType allocator;
    Value a(kArrayType);
    a.PushBack(5, allocator);
    a.PushBack(1, allocator);
    a.PushBack(3, allocator);
    std::sort(a.Begin(), a.End(), ValueIntComparer());
    EXPECT_EQ(1, a[0].GetInt());
    EXPECT_EQ(3, a[1].GetInt());
    EXPECT_EQ(5, a[2].GetInt());
}
#endif

During the testing, I found that there are some warnings in C++11 compilation, and have been fixed in #515.

All 3 comments

std::sort requires

  1. a pair of random access iterators
  2. a user provided comparison functor
  3. Values can be std::swap-ed

The array in RapidJSON is implemented as plain C/C++ array(See struct Array in document.h, and there is no memory/access overhead),
so it satisfies the requirements of random access.
The iterators can be provided by GenericValue::Begin and GenericValue::End function.

A custom comparison functor is a struct which has an operator().
It looks like

struct Comp {
    bool operator()(const Value& lhs, const Value& rhs) const {
        return lhs.GetInt() < rhs.GetInt();
    }
};

I am not very sure of the swapping of Values.
I tried to sort an array of ints and it just works.
Since copy is not allowed in GenericValue(private copy constructor),
I guess that the swap works successfully with no extra memory allocation or value copy.

These documents may be helpful for you:
http://rapidjson.org/md_doc_tutorial.html#QueryArray
http://rapidjson.org/md_doc_tutorial.html#ModifyArray

If your data cannot fit into main memory or you do not want to sort in place,
I would suggest to use SAX API to store the data into another place.

I tried on clang. its C++03 version of std::sort seems require copy constructor, which is not supported by Value.

However, in C++11 std::sort only requires the types to be MoveAssignable and MoveConstructible.

And it works with RAPIDJSON_HAS_CXX11_RVALUE_REFS=1

struct ValueIntComparer {
    bool operator()(const Value& lhs, const Value& rhs) const {
        return lhs.GetInt() < rhs.GetInt();
    }
};

#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, Sorting) {
    Value::AllocatorType allocator;
    Value a(kArrayType);
    a.PushBack(5, allocator);
    a.PushBack(1, allocator);
    a.PushBack(3, allocator);
    std::sort(a.Begin(), a.End(), ValueIntComparer());
    EXPECT_EQ(1, a[0].GetInt());
    EXPECT_EQ(3, a[1].GetInt());
    EXPECT_EQ(5, a[2].GetInt());
}
#endif

During the testing, I found that there are some warnings in C++11 compilation, and have been fixed in #515.

I think this is fully resolved.

Was this page helpful?
0 / 5 - 0 ratings