0

I want to sort the following information by the string value (not the key number). I am able to convert it to a dictionary and order by value ("AAA" and "CCC") in the code below... now the only question is, how do I convert the dictionary to the same format below in the parseJSON function? I cannot change the format of the JSON so that's out of the question. Any other ways are appreciated. I cannot move it to an array or anything. As stated in my question, the JSON format exists as is and I cannot change it.

   var studentCollection.Groups = $.parseJSON("{\"1000\":\"CCC\", \"1001\":\"AAA\"}");

    //Sorting the studentCollection.Groups dictionary. 
    //Even though the groups come back as valid/sorted JSON
    //upon parsing the JSON, the groups sorting gets lost
    var items = Object.keys(studentCollection.Groups).map(function (key) {
        return [key, studentCollection.Groups[key]];
    });

    items.sort(function (first, second) {

        if (first[1] < second[1])
            return -1;
        if (first[1] > second[1])
            return 1;
        return 0;

    });
Saturn K
  • 2,705
  • 4
  • 26
  • 38
  • 2
    Are you asking how to convert your multi-dimensional array stored in `items` back into an object? Why do you care about ordering for an object? Object properties do not have meaningful "ordering" by definition. – Mike Brant Sep 11 '15 at 22:02
  • possible duplicate of [Sorting JavaScript Object by property value](http://stackoverflow.com/questions/1069666/sorting-javascript-object-by-property-value) – Oli Beatson Sep 11 '15 at 22:02
  • The problem is that, if you convert the sorted array back to an object, since objects have no order, it would have been useless. So either stringify the array, or build your own JSON stringifier. – Oriol Sep 11 '15 at 22:06
  • As stated, these are the codes that I am given. I have to give a sorted object (not dictionary or array) back to the caller of this function. I don't make the rules, I just follow them. – Saturn K Sep 11 '15 at 22:06
  • @KeyvanSadralodabai: There is no such thing as a "sorted object". What you want is impossible. – Felix Kling Sep 11 '15 at 22:09
  • It's completely possible... What do you mean? – Saturn K Sep 11 '15 at 22:10
  • 1
    The order of properties of an object is only guaranteed for some methods (e.g. `Object.keys`, and also only in ES6) and is pretty much restricted to non-numeric keys (which you don't have). There is no concept of an "ordered/sorted object". If you are generally iterating over the object with `for...in`, there is no guarantee of order. – Felix Kling Sep 11 '15 at 22:14

2 Answers2

1

you can just convert your object values to array which you will sort and then again assign step-by-step to an object:

    var j = "{\"1000\":\"AAA\", \"1001\":\"ZZZ\"}";
    var o = JSON.parse(j);

    var keys = Object.keys(o);
    var values = [];

    for(var i = 0; i < keys.length; i++) values.push(o[keys[i]]);

    values.sort();

    for(var i = 0; i < values.length; i++) o[keys[i]] = values[i];

    alert( JSON.stringify(o) );

UPDATE

since example above has not keep the keys base order this one should:

    var j = "{\"1000\":\"AAA\", \"1002\":\"ZZZ\", \"1004\":\"DDD\", \"1003\":\"BBB\", \"1001\":\"YYY\"}";

    j = j.replace(/\"\d+\"\:/g, function myFunction(x){ return x.substring(0,1) + "_" + x.substring(1) })

    var o = JSON.parse(j);

    var keys = Object.keys(o);
    var values = [];

    for(var i = 0; i < keys.length; i++) values.push(o[keys[i]]);

    values.sort();

    for(var i = 0; i < values.length; i++) o[keys[i]] = values[i];

    var j = JSON.stringify(o)

    j = j.replace(/\"\_\d+\"\:/g, function myFunction(x){ return x.substring(0,1) + x.substring(2) })

    alert( j );

try it here: https://jsfiddle.net/pyqw8hvt/1/

the idea is to add _ before every integer key to make it non-integer and in this way avoid automatic sorting inside parsed object, and then after stringifying the object erase the added _ inside keys

m.antkowicz
  • 13,268
  • 18
  • 37
  • Can you clarify how `JSON.stringify` determines the order of properties for objects? – Felix Kling Sep 11 '15 at 22:10
  • why would it? it is only for convert "sorted" object back to JSON – m.antkowicz Sep 11 '15 at 22:11
  • Why would it what? I was asking how `JSON.stringify` iterates over the object properties for serialization. *edit:* Or maybe I am mistakenly assuming that the OP wants to get JSON as result... – Felix Kling Sep 11 '15 at 22:12
  • The issue is that in your example, the "Property Names" ("1000", "1001") are also in order... I want the property names to not be ordered and the property values to be ordered. – Saturn K Sep 11 '15 at 22:14
  • hm the funny thing is that **var o = JSON.parse(j);** this is already "sorting" an object since keys are integers - I'm not sure if it is possible to get unordered integer type key object – m.antkowicz Sep 11 '15 at 22:22
  • 1
    @KeyvanSadralodabai Javascript doesn't specify anything about the order of properties in an object. If you want specific order of elements, you use arrays, not objects. – Barmar Sep 11 '15 at 22:37
1

I don't know if this is the best way to do it, you'd have to call JSON.stringify twice, but it gives the output you're looking for:

var studentCollection = {};
studentCollection.Groups = $.parseJSON("{\"1000\":\"CCC\", \"1001\":\"AAA\"}");

var items = Object.keys(studentCollection.Groups).map(function (key) {
    return [key, studentCollection.Groups[key]];
});

items.sort(function (first, second) {
    if (first[1] < second[1])
        return -1;
    if (first[1] > second[1])
        return 1;
    return 0;
});

result = JSON.stringify(JSON.stringify(toObject(items)))
console.log(result);
// outputs: "{\"1001\":\"AAA\",\"1000\":\"CCC\"}"

// checking if ordering remains
console.log($.parseJSON(result));
// outputs: {"1001":"AAA","1000":"CCC"}

function toObject(arr) {
    return arr.reduce(function(o, v, i) {
        o[v[0]] = v[1];
        return o;
    }, {});
}
Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
  • Right, but when I convert back from JSON to object, it loses its sorting. – Saturn K Sep 11 '15 at 22:11
  • I did your edited "$.parseJSON(result)" and it doesn't keep ordering for the large object that I have. It is known that $.parseJSON doesn't keep the ordering of the JSON string – Saturn K Sep 11 '15 at 22:19
  • 1
    Can you provide us with that object, or at least one example where it doesn't work, either by including it in your question or providing a JSFiddle? – Marcos Dimitrio Sep 11 '15 at 22:21