Iterating through a nested Dictionary and changing values based on type

So I’m attempting to create a serialization function that will take a nested dictionary of unknown index/value pairs, then convert (for example) all Vector3 values to a dictionary format that can be processed by a DataStore:

-- Example Dictionary:
local Dict = {
	X = {
		Y = {
			Z = Vector3.new(1, 2, 3);
		};
	};
	Y = {
		X = Vector3.new(2, 3, 4);
	};
};

Should be converted to (for example):

local Dict = {
	X = {
		Y = {
			Z = {X = 2, Y = 3, Z = 4};
		};
	};
	Y = {
		X = {X = 2, Y = 3, Z = 4};
	};
};

My issue is with changing dictionary values from within an interative function. Something like this:

local function Serialize(Dict)
	local IterateDictionary; IterateDictionary = function(Dict)
		for Index,Value in pairs(Dict) do
			if (type(Value) == 'table') then
				IterateDictionary(Dict[Index]);
			elseif (type(Value) == 'Vector3') then
				Table[Index] = {X = Value.X, Y = Value.Y, Z = Value.Z};
			end
		end
	end
	IterateDictionary(Dict);
	return Dict;
end

Will not work as the ‘Dict’ variable being passed to the next iteration is locally defined in a new scope, so changes will not be made to the original ‘Dict’ that I end up returning. I believe I managed this years ago by passing a table of indexes to the next iteration, then looping through the indexes to change the value, but it was cumbersome and I can’t find that original script.

If anyone has any suggestions or alternatives then I would be grateful. I had an idea about returning values to the previous iteration but I’ve been scripting for about 6 hours and my brain isn’t able to process this at the moment.

(Also before someone suggests it, I can’t use a known-length/depth dictionary as it will be procedurally generated based on how users interact with the game)

Apologies if this isn’t what you’re looking for. But you could use a recursive system as such:

local function serialize(t: {[any]: any})
	local serialized = {}
	
	for key, value in t do
		local valueType = typeof(value)
		if valueType == "Vector3" then
			serialized[key] = {x = value.X, y = value.Y, z = value.Z}
		elseif valueType == "table" then
			serialized[key] = serialize(value)
		end
	end
	
	return serialized
end

Exactly what I was looking for, cheers!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.