I have a json object with "numeric" (so to say) keys, associated to actual numeric values; example:
{"12":5,"8":9,"21":3}
Since json.sort only works with arrays, how can I order it so that they go from the key with the highest value to the lowest?
For the example, the desired result would be:
{"8":9,"12":5,"21":3}
"8" has the highest value, "12" the second, and "21" the lowest.
Sorting json object by values
Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice
Sorting json object by values
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: Sorting json object by values
You manually deconstruct and rebuild the json object. I'm sure I have some generic code somewhere for this.
Here's a rewrite of json.sort:
Here's a rewrite of json.sort:
Code: Select all
[H: data = arg(0)]
[H, if(argCount() >= 2): direction = arg(1); direction = "a"]
[H, if(json.isEmpty(direction)): direction = "a"; direction = substring(lower(direction),0,1)]
[H, if(json.type(data) == "OBJECT"), code: {
[H: keys = oldFunction(json.fields(data,"json"),direction)]
[H: newObj = "{}"]
[H, foreach(key,keys): newObj = json.set(newObj,key,json.get(data,key))]
};{
[H: counter = 0]
[H: args = ""]
[H, foreach(arg,macro.args), code: {
[H: args = listAppend(args,"arg"+counter)]
[H: set("arg"+counter,arg(counter))]
[H: counter = counter + 1]
}]
[H: newObj = eval(strformat("oldFunction(%{args})"))]
}]
[H: macro.return = newObj]
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Sorting json object by values
Thanks for the reply, but I'm not sure how to make it work...
I pasted that code in a macro on a Lib token, and in onCampaignLoad I defined the function "json.sortObjByVal".
Yet, even after reloading, I get:
"Old definition for function json.sortObjByValdoes not exist"
What's wrong?
I pasted that code in a macro on a Lib token, and in onCampaignLoad I defined the function "json.sortObjByVal".
Yet, even after reloading, I get:
"Old definition for function json.sortObjByValdoes not exist"
What's wrong?
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: Sorting json object by values
json.sort is an existing function and my code overwrites it. If you want to make it a separate function just change oldFunction() to json.sort().
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Sorting json object by values
Ah, clear, thanks.
Now, looking at it in haste, from what I understand, it gets the fields and sorts them in an array, then uses that array to retrieve the respective values and create an object. But that object is sorted by fields and not values.
I have a half-idea on how to make it work, but I'm not sure, presently I'm in a hurry, I'll look into it later or tomorrow.
Now, looking at it in haste, from what I understand, it gets the fields and sorts them in an array, then uses that array to retrieve the respective values and create an object. But that object is sorted by fields and not values.
I have a half-idea on how to make it work, but I'm not sure, presently I'm in a hurry, I'll look into it later or tomorrow.
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
Re: Sorting json object by values
Yep, that's the way I wrote that so I can have my keys in alphabetical order. If you want to sort the object by value and reorder the keys then you can create an array of objects and use the normal json.sort on it then rebuild the object.
output:
IMO, the above is shorthand for what the values really mean. ie the key represents something as does the value and should actually be in an array of objects instead of a single object. For example: [{"carNumber":8,"initiative":9},{"carNumber":12,"initiative":5}] I don't know what it actually means, but I think it's something similar.
Code: Select all
[H: myObj = '{"12":5,"8":9,"21":3}']
[H: myArray = "[]"]
[H, foreach(key,myObj): myArray = json.append(myArray,json.set("{}","key",key,"value",json.get(myObj,key)))]
[H: myArray = json.sort(myArray,"d","value")]
[H: newObj = "{}"]
[H, foreach(obj,myArray): newObj = json.set(newObj,json.get(obj,"key"),json.get(obj,"value"))]
[dialog("D"):{<pre>[R: json.indent(replace(newObj,"<","<"))]</pre>}]
Code: Select all
{
"8": 9,
"12": 5,
"21": 3
}
Downloads:
- Notepad++ MapTool addon
- RPEdit details (v1.3)
- Coding Tips: Modularity and Design
- Videos: Macro Writing Tools
Re: Sorting json object by values
Json objects are unordered like most key/value hash tables.
Some solutions may seems to work, but are implementation specific and your object order is subject to change. Especially if you use some java lib in the meantime.
I've not much experience in java/mt, but in python I ran into some very nasty issues, because of the unordered nature of json/dict.
For {"12":5,"8":9,"21":3}
you probably need a function that returns
[{"21":3}, {"12":5},{"8":9}], ie an aray of json object
Some solutions may seems to work, but are implementation specific and your object order is subject to change. Especially if you use some java lib in the meantime.
I've not much experience in java/mt, but in python I ran into some very nasty issues, because of the unordered nature of json/dict.
For {"12":5,"8":9,"21":3}
you probably need a function that returns
[{"21":3}, {"12":5},{"8":9}], ie an aray of json object
Re: Sorting json object by values
Thanks, helpful as usual.aliasmask wrote: ↑Fri May 11, 2018 7:34 pmYep, that's the way I wrote that so I can have my keys in alphabetical order. If you want to sort the object by value and reorder the keys then you can create an array of objects and use the normal json.sort on it then rebuild the object.
output:Code: Select all
[H: myObj = '{"12":5,"8":9,"21":3}'] [H: myArray = "[]"] [H, foreach(key,myObj): myArray = json.append(myArray,json.set("{}","key",key,"value",json.get(myObj,key)))] [H: myArray = json.sort(myArray,"d","value")] [H: newObj = "{}"] [H, foreach(obj,myArray): newObj = json.set(newObj,json.get(obj,"key"),json.get(obj,"value"))] [dialog("D"):{<pre>[R: json.indent(replace(newObj,"<","<"))]</pre>}]
IMO, the above is shorthand for what the values really mean. ie the key represents something as does the value and should actually be in an array of objects instead of a single object. For example: [{"carNumber":8,"initiative":9},{"carNumber":12,"initiative":5}] I don't know what it actually means, but I think it's something similar.Code: Select all
{ "8": 9, "12": 5, "21": 3 }
"There are many ways my Son, to find where the souls of Demons remain...
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."
But it takes only one second of despair and of doubt until, at last, your Soul they will gain..."