Help requested with json array

Thoughts, Help, Feature Requests, Bug Reports, Developing code for...

Moderators: dorpond, trevor, Azhrei

Forum rules
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior. :)
Post Reply
User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Help requested with json array

Post by wolph42 »

I'm looking for a smart method to change this:

Code: Select all

[r:X_4='[{"x":4,"y":4},{"x":4,"y":4},{"x":4,"y":4},{"x":1,"y":1},{"x":4,"y":1},{"x":4,"y":1},{"x":4,"y":4}]']  
into this

Code: Select all

[r:X_4='[{"x":4,"y":4,"number":3},{"x":1,"y":1,"number":1},{"x":4,"y":1,"number":2}]']  
basically, every coordinate that is double/triple/etc should be removed BUT its occurance must be counted and added to that coordinate.
so its not a simple Wiki: json.unique()

Note that the 'real' array is much more complex with more keys, but for clarity reasons I reduced it to this simpler version.

Thank you!

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

Re: Help requested with json array

Post by aliasmask »

The best method may depend on how big the array and how often you expect to have duplicates. Not knowing anything about the data beyond that I would suggest the following:

Code: Select all

array = json.sort(array)
continue = 1
end = array size
index = 0
newArray = []
while continue
   value = get(array,index)
   count = json.count(array,value)
   newArray = json.append(newArray,json.set(value,"number",count))
   index = index + count
   if index >= end then continue = 0
   
I do the sort because it groups all the same values together. So, you grab the first one then increment by the count giving you the next unique value. Here's another method that would likely be faster but far more complicated to build.

Code: Select all

array = json.sort(array)
uArray = json.unique(array)
dupeCount = json.size(array) - json.size(uArray)
<!-- complicated regex to find duplicate entries -->
dupesFound = getFindCount(id)
for i,1,dupesFound+1
   string = getGroup(id,i,0)
   <!-- get base coords -->
   <!-- count those coords in string -->
   <!-- remove from array -->
   <!-- add new coords with count to array -->
edit: Btw, that complicated regex part can be found here: http://forums.rptools.net/viewtopic.php ... 54#p248454

User avatar
bubblobill
Giant
Posts: 167
Joined: Sun Jan 24, 2010 3:07 pm

Re: Help requested with json array

Post by bubblobill »

and because everyone does everything differently, I did it this way.

Code: Select all

[r:X_4='[{"x":4,"y":4},{"x":4,"y":4},{"x":4,"y":4},{"x":1,"y":1},{"x":4,"y":1},{"x":4,"y":1},{"x":4,"y":4}]']  	 	

[newX_4=""]
[X_4=json.sort(X_4)]
[unique.coordinates=json.unique(X_4)]
[thecount=json.length(unique.coordinates)]

[for(ii, 0, thecount),code:{
	[thisCoordinate=json.get(unique.coordinates, ii)]
	[thisCount = json.count(X_4,(json.get(unique.coordinates, ii)))]
	[thisCoordinate=json.set(thisCoordinate, "number", thisCount)]
	[newX_4 = json.append(newX_4,thisCoordinate)]
	}]
I also did it by using json.indexOf where the count was the difference between the indices of the various co-ordinates.
Not sure which method would be systemically quicker.

Bubblobill
Who's got your nose?
Bubblobill on the forum.
@Reverend on the MapTool Discord Server

Responsible for less atrocities than most... I do accept responsibility for these though: SmartDoors, Simple d20 Framework - barebones, Drop-in: All 3.5 SRD Monsters, Drop in: Simple Character Editor, Battletech Framework

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

Re: Help requested with json array

Post by wolph42 »

Thanks for the replies... strange as I replied to the topic earlier with an answer I finally came up with, but now i see it got eaten by the big bad interweb.

Here's what I dug up:

Code: Select all

    
<!-- array == X_4 and Damage == Number -->
[gslUnique    = json.unique(array)]
[gslTmp        = "[]"]
[foreach(object, gslUnique): gslTmp = json.append(gslTmp, json.set(object, "Damage", json.count(array, object) ))]
 
which is similar, but not quite the same, to bublobills method.

Btw: I was happily surprised that the order inside the objects does not matter for the count and unique. So
{x:4,y:4} == {y4,x:4}

User avatar
JML
Dragon
Posts: 515
Joined: Mon May 31, 2010 7:03 am
Location: Blagnac, France

Re: Help requested with json array

Post by JML »

Beware that, compared to aliasmask's solutions, yours and bubblobill's are likely to be performance hogs.

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

Re: Help requested with json array

Post by wolph42 »

JML wrote:Beware that, compared to aliasmask's solutions, yours and bubblobill's are likely to be performance hogs.
usually I would have to agree, In this particular case however, I doubt it. I've ran numerous benchmark tests for speed and although untested in this case, I'm quite confident that my method is actually the fastest. For one, I have a shorter loop (less cycles) than AM and that has quite some impact. next to that, every separate line of code also takes time over condensing code into one line.

User avatar
JML
Dragon
Posts: 515
Joined: Mon May 31, 2010 7:03 am
Location: Blagnac, France

Re: Help requested with json array

Post by JML »

I was thinking of hidden loops: json.unique and json.count should rely on inner loops to perform their tasks. And both on the full size array.

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

Re: Help requested with json array

Post by aliasmask »

wolph42 wrote:
JML wrote:Beware that, compared to aliasmask's solutions, yours and bubblobill's are likely to be performance hogs.
usually I would have to agree, In this particular case however, I doubt it. I've ran numerous benchmark tests for speed and although untested in this case, I'm quite confident that my method is actually the fastest. For one, I have a shorter loop (less cycles) than AM and that has quite some impact. next to that, every separate line of code also takes time over condensing code into one line.
Based on my first example, I think wolph is right that his would be faster. It takes time to define and increment a counter. But the second one would only loop as many times as there are duplicates rather than the whole array.

Post Reply

Return to “MapTool”