Let's say I have a JSONEncoded table that looks like this:
l = "[24,24,24,24,24,55,12,12,56,87,87,87,87,92]"
I want to turn it into something like this:
l = "[24.5,55,12.2,56,87.4,92]"
So the .
is really an exponent symbol ^
.
I've already tried my hand at this, and it somewhat worked. The problem is that it mixes parts my table up. Here is my script so far (although it uses a model's children for the table, not a JSONEncoded table). A script that formats JSONEncoded tables or a model's children would be helpful.
ImgScript = {} --The main holder for all of the color values Temp = {} --The temporary holder for color values. This is so we can collect the '4, 4, 4' and turn it into '4^3'. Due to JSON limitations, the ^ has to be replaced with a . So when you see 4.3, remember it means 4, 4, 4! for index, child in pairs(workspace.IMG:GetChildren()) do n = child.BrickColor.Number if n == Temp[1] then Temp[2] = Temp[2] + 1 else if #Temp == 0 then table.insert(Temp, n) table.insert(Temp, 1) else table.insert(ImgScript, Temp[1] .. '.' .. Temp[2]) Temp = {} table.insert(Temp, n) table.insert(Temp, 1) end end end
You're looking at something similar to RLE.
local parsed = {}; local last,le = '',0 jsonTable:sub(2,-2):gsub('[^,]+',function(c) le=le+1 if last ~= c then if le == 1 then parsed[#parsed+1] = last else parsed[#parsed+1] = last..'.'..le end last = c; le = 0 end end) parsed = '['..table.concat(parsed,',')..']'
Parsed is now your compressed table. If you need things explaining I'll do it later because I'm not at a computer and it's tricky typing here. I'll also sort out my code formatting when I get on a computer.
The term for this is run-length encoding, because you write the length (number of things) in a "run" (same thing over and over).
If you have an actual table input
, and you want to make an actual table, output
, code to do this might look like this:
local output = {} for i = 1, #input do if input[i] ~= input[i-1] then -- Start of a new run! local len = {} for j = i, #input do -- Figure out how long the run is if input[i] ~= input[j] then len = j - i break end end -- Record the run (even if it's length 1) table.insert(output, {value = input[i], run = len}) end end
Without peeking-ahead like the above, you could write it like this:
local output = {} local last = input[1] local run = 1 for i = 2, #input+1 do -- +1 to deal with the last run if input[i] ~= last then table.insert(output, {value = last, run = run}) else run = run + 1 end end