How can I tell if an array is mixed?

How can I tell if an array/table is a ‘Mixed array / dictionary’? If so I’d like to loop through my table and change the values that are causing my table to be a mixed array to values that wont make my array a mixed dictionary/array but while also still having the same value.

local _DATASTORE_SEVER = game:GetService("DataStoreService"):GetDataStore("____SEERRRVVVEEREEEERR_DDDAAAATTTTAAAAAAA_______")

local DAATA = {
	test = {
		Ones = 6,
		Twos = 8,
		Yess99 = false,
		Name = "BobCat",
		Offsale = nil, --MIXED ARRAY.
	}

}
print(type(DAATA.test.Offsale))
if DAATA.test.Offsale == nil then
  --TODO: LOOP THROUGH TABLE AND TURN THE TABLE FROM MIXED ARRAY TO NON MIXED ARRAY
  --NOTE: 'Offsale' MUST still say 'nil' in some form or way
end

_DATASTORE_SEVER:SetAsync("TEST", DAATA)
local data = _DATASTORE_SEVER:GetAsync("TEST")

if data == nil then
	local Save__DATA, _message = pcall(function()
		_DATASTORE_SEVER:SetAsync("TEST", DAATA)
	end)

	if Save__DATA == true then
		print("Saved ")
	else
		warn(_message)
	end
else
	print(data)
end

I was wondering how I could go about fixing this with code

Maybe instead of trying to modify your table, you would try to convert it to JSON string.

I tried that. It did the same thing. It didn’t save all my values

Hope this helps!

local function isMixedDictionary(dict)
	local dictType
	for _, value in pairs(dict) do
		if not dictType then
			dictType == type(value)
			continue
		end
		
		if not (type(value) ~= dictType) then continue end
		
		return true
	end
	
	return false
end

That works for part of my issue. Now I’d like to loop through my table and change the values that are causing my table to be a mixed array to values that wont make my array a mixed dictionary/array but while also still having the same value. If that makes sense

You tried
game:GetService(“HTTPService”):JSONEncode(dictionary)?
If that doesn’t work you can convert everything to a string. The deserialization process might be a bit difficult with some of them though.

Yes I tried it and it was no good.

I think I read this post wrong, my bad :sweat_smile:

Don’t you just need to change the number keys to string keys? To do that just go through the table and use ""..key on all the keys. If your table has more than a single layer then just do that recursively.

If your table uses keys that aren’t strings or numbers just have a function list to convert those values to strings and run the proper function on the key value.

1 Like
local function isMixedTableRecursive(t)
	local _type
	for _, v in pairs(t) do
		if not _type then
			_type = type(v)
		else
			if _type ~= type(v) then
				return true
			end
		end
		if type(v) == "table" then
			if isMixedTableRecursive(v) then
				return true
			end
		end
	end
	return false
end

local t = {{1, 2, 3}, {"A", "B", "C"}}
local isMixed = isMixedTableRecursive(t)
print(isMixed) --false

t = {{1, 2, 3}, {true, false, {}}}
isMixed = isMixedTableRecursive(t)
print(isMixed) --true

For edge-cases where a table’s values are table values.

1 Like
local function convertMixedTableRecursive(t)
	for i, v in pairs(t) do
		if type(v) ~= "string" then
			if type(v) == "table" then
				convertMixedTableRecursive(v)
			else
				t[i] = tostring(v).."~"..type(v)
			end
		end
	end
end

local test = {Ones = 1, Twos = 2, Threes = 3, True = true, False = false}

convertMixedTableRecursive(test)
for _, v in pairs(test) do
	print(v)
end

local function revertMixedTableRecursive(t)
	for i, v in pairs(t) do
		if v:match("number$") then
			v = v:gsub("~number", "")
			t[i] = tonumber(v)
		elseif v:match("^true~") then
			t[i] = true
		elseif v:match("^false~") then
			t[i] = false
		elseif type(v) == "table" then
			revertMixedTableRecursive(v)
		end
	end
end

revertMixedTableRecursive(test)
for _, v in pairs(test) do
	print(v)
end

image

Currently handles tables, strings, numbers, Booleans and nil.
Doesn’t handle threads, functions and userdata.

1 Like