akheron / jansson

C library for encoding, decoding and manipulating JSON data
http://www.digip.org/jansson/
Other
3.02k stars 807 forks source link

Implement json_compare() function. #684

Open solemnwarning opened 3 months ago

solemnwarning commented 3 months ago

This commit introduces a json_compare() function which can be used to compare `json_t structures for sorting purposes.

solemnwarning commented 3 months ago

I'm not really sure why the CI is failing for VS <2013.

1>..\src\value.c(746) : error C2143: syntax error : missing ';' before 'type'

    for (i = 0; i < min_size; i++) {
        json_t *value1, *value2;

        value1 = json_array_get(array1, i);
        value2 = json_array_get(array2, i);

        int result = json_compare(value1, value2); /* <-- Line 746 */
        if (result != 0)
            return result;
    }
akheron commented 3 months ago

Thanks for the PR!

What's the use case where you want to compare two arbitrary JSON values for ordering? As far as I know this is not common in programming languages, for example. In some languages you can compare any values, but they're coerced to strings first...

... which leads to the fact that you could also achieve this in Jansson by encoding to a string first and then comparing the strings. This would yield a stable ordering, and would even have a better worst-case time complexity, as it would avoid the loop in object comparison code that look like O(n^2) to me.

solemnwarning commented 3 months ago

That Ubuntu CI job highlighted the problem... been a long time since I've had to write C89 compliant code.

My use case here is a map which includes a blob of arbitrary JSON as part of the key. I've actually got it implemented by serialising it to a string and then comparing that as described, however I'm not a fan of it since it means either keeping the serialised form around, or serialising on every operator< call and potentially having an allocation failure.

For my use case at least, the data structures are small so the inefficient sorting doesn't really matter.