Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do I compress tables?

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

4 comments

1

Is the order of the list significant?

1

You are going through the table in pairs. This does not specifically iterate over every index in order. Have you tried ipairs?

0

@BlueTaslem Yes the order of the list is significant

0

@randomsmileyface Changing pairs to ipairs didn't change the output. The numbers are still out of order, although the exponents are right.

2 answers

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.

2 comments

0

Thanks, this somewhat solved my answer. The output isn't disorganized like the output of my script, so that is a +1. The end and beginning of the output are a little funky though, being [,[24,24.4,55,12.2,56,87.4]

1

Ah that was my bad. I forgot to strip the [] from the JSONTABLE. I've edited my answer to try and solve this.

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

This discussion is preserved as it was. New answers, comments, and votes are closed.