[solved]json.sort objects

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

[solved]json.sort objects

Post by wolph42 »

I've devised a fast method to sort json objects, but as I want to make a UDF out of it I get stuck and its unclear where. Basically this is the entire code:

Code: Select all

[h:'<!-- ---------------------- json.sort (array, direction, optional:json.key) OBJECT ALSO ---------------------- -->']
[h:isArray    = if(json.type(arg(0) == "ARRAY"),1,0)]
[h, if(  argCount() < 3 || isArray ), CODE:{
    [if(argCount() > 1): direction = arg(1) ; direction = "ascending"]
    [macro.return    = oldFunction(json.sort(arg(0), direction))]
};{
    [sorted            = oldFunction(json.sort(   replace("["+substring(arg(0), 1, length(arg(0))-1)+"]", '("[^"]+")\\:\\{', '{"tmpJonsSortName":\$1,'), arg(1), arg(2)   ))]
    [macro.return    = "{"+substring(replace(sorted, '\\{"tmpJonsSortName"\\:("[^"]+"),', '\$1:{'), 1, length(replace(sorted, '\\{"tmpJonsSortName"\\:("[^"]+"),', '\$1:{'))-1)+"}"]
}]  
together with

Code: Select all

[h:defineFunction("json.sort", "json.sort@lib:jsonSortObject", 0, 1)] 
but it renders an error. When I test it on an object and remove the if statement so:

Code: Select all

    [sorted            = oldFunction(json.sort(   replace("["+substring(arg(0), 1, length(arg(0))-1)+"]", '("[^"]+")\\:\\{', '{"tmpJonsSortName":\$1,'), arg(1), arg(2)   ))]
    [macro.return    = "{"+substring(replace(sorted, '\\{"tmpJonsSortName"\\:("[^"]+"),', '\$1:{'), 1, length(replace(sorted, '\\{"tmpJonsSortName"\\:("[^"]+"),', '\$1:{'))-1)+"}"]
 
I get a recursive loop limit and it appears that json.sort keeps calling the UDF instead of the Wiki: oldFunction(). Anyone know why this happens?

For testing purposes, it contains the above code and a test function to try it out. If you use the debug console you'll see the recursive loop which shouls not happen.:
REMOVED

REsolved: here the working lib:
lib:jsonSortObject

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: json.sort objects

Post by aliasmask »

This is the code I use:

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] 

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: json.sort objects

Post by wolph42 »

yeah I've seen it before, its a much slower method. I've tested my method and it works and is really fast...however as soon as I try to embed it into a UDF I get the recursive issue, and I don't understand why.

edit: o crap I think I know what I did wrong. Thank you for the example, I now see the error of my ways.

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: json.sort objects

Post by aliasmask »

You probably just figured it out, but you're using json.sort in your json.sort which would give you the recursion. So, in your method, you just change the outer object in to an array where the key is made the beginning allowing the regular function to sort and then change the string back to the original object. Yeah, that would be faster than rebuilding the objects especially if the object was big.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: json.sort objects

Post by wolph42 »

yeah I figured it out. here the correct lib
lib:jsonSortObject

by the way, I had a look at your code and there is a subtle difference with mine. Yours sorts an json object by keys. Mine sorts json objects by their values. E.g.

Code: Select all

{test:{x:3,y:2}, test1:{x:5,y:3}, test0:...}
you sort test, test1 etc.
my function is able to sort on the values of 'x' or 'y'.

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: json.sort objects

Post by aliasmask »

Ah, that would explain all the regex. Yeah, sorting by the keys is what I needed for my code.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: json.sort objects

Post by wolph42 »

this one can also sort by keys and is most likely (a lot) faster, to do that you have to pass on "tmpJonsSortName" as sorting value.

User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: [solved]json.sort objects

Post by aliasmask »

If I had the need I would totally do the regex thing, but the lists I deal with are relatively short and I don't care about the data value of the object. It's basically a named array.

Post Reply

Return to “Macros”