Manticore Manticore - 5 months ago 7
JSON Question

Sorting a JSON objects' child-keys by their child-keys' values

I am looking for a way to sort my three main JSON keys (

neutral
,
positive
,
negative
) using their children
y
-keys' values.

This is how the JSON object is set up:

{
"chartSeries" : {
"negative" : [ {
"y" : 1505,
"url" : "http://www.test.com/1"
}, {
"y" : 425,
"url" : "http://www.test.com/2"
}, {
"y" : 1046,
"url" : "http://www.test.com/3"
} ],
"neutral" : [ {
"y" : 10,
"url" : "http://www.test.com/4"
}, {
"y" : 1,
"url" : "http://www.test.com/5"
}, {
"y" : 2,
"url" : "http://www.test.com/6"
} ],
"positive" : [ {
"y" : 230,
"url" : "http://www.test.com/7"
}, {
"y" : 50,
"url" : "http://www.test.com/8"
}, {
"y" : 483,
"url" : "http://www.test.com/9"
} ]
}
}


Let's say I want to sort the
negative
values descending by
y
's value, then my JSON should look like this:

{
"chartSeries" : {
"negative" : [ {
"y" : 1505,
"url" : "http://www.test.com/1"
}, {
"y" : 1046,
"url" : "http://www.test.com/3"
}, {
"y" : 425,
"url" : "http://www.test.com/2"
} ],
"neutral" : [ {
"y" : 10,
"url" : "http://www.test.com/4"
}, {
"y" : 2,
"url" : "http://www.test.com/6"
}, {
"y" : 1,
"url" : "http://www.test.com/5"
} ],
"positive" : [ {
"y" : 230,
"url" : "http://www.test.com/7"
}, {
"y" : 483,
"url" : "http://www.test.com/9"
}, {
"y" : 50,
"url" : "http://www.test.com/8"
} ]
}
}


note how the negative elements are ordered by their descending y-values and neutrals' and postives' values are ordered exactly in the same sequence.

I tried parsing it as Javascript object using
JSON.parse()
and then using a sort function:

function sortResults(data, prop, asc) {
sorted_data = data.sort(function(a, b) {
if (asc) return (a[prop] > b[prop]);
else return (b[prop] > a[prop]);
});
return sorted_data;
}


But I just get "TypeError: data.sort is not a function" in my debugger.

Any explanations or advices are kindly appreciated!

Answer

I'll stick with JSON.sortify (https://www.npmjs.com/package/json.sortify) as it perfectly suits my needs.

The code behind that magical function:

function sortKeys(o) {
    if (Array.isArray(o)) {
        return o.map(sortKeys)
    } else if (o instanceof Object) {
        var _ret = function() {
            var numeric = [];
            var nonNumeric = [];
            Object.keys(o).forEach(function(key) {
                if (/^(0|[1-9][0-9]*)$/.test(key)) {
                    numeric.push(+key)
                } else {
                    nonNumeric.push(key)
                }
            });
            return {
                v: numeric.sort(function(a, b) {
                    return a - b
                }).concat(nonNumeric.sort()).reduce(function(result, key) {
                    result[key] = sortKeys(o[key]);
                    return result
                }, {})
            }
        }();
        if (typeof _ret === "object") return _ret.v
    }
    return o
};

And that's it.

Comments