Check if variable is an array

When dealing with buffers and I need to combine multiple buffers into one main buffer. I send those multiple buffers inside a table into a function. Sometimes the table of buffers are index based and their size aren’t pre-defined. This is likely data that just needs serializing for sending over the network, but it can grow or shrink so it’s impossible to set a pre-defined buffer size.

Other data is pre-defined such as player stats, this would be in a table with a dictionary key named [“player_stats”] because the system would know how to calc the offsets to read/write the proper data in the buffer.

I’m going to experiment with that. I love learning new things. I rarely use __newindex but I faithfully use .__index for my classes. This is why I love discussions I walk away with something new.

1 Like

Maybe this would work better:

local function isArray(t)
    if type(t) ~= "table" then return false end

    local i = 1
    for k, _ in t do
      if type(k) ~= "number" or k ~= i then
        return false
        end
        i += 1
    end

    return true
end

@12345koip Why would you need the __newindex metamethod? Arrays can still be modified in Roblox with the use of table.insert(), table.remove(), and indexing numbers. Also, the __newindex in your code won’t affect the array at all because you didn’t use setmetatable().

Instead, @LucidBits’s code would be the solution because arrays are basically dictionaries with numbers as the keys (or what would we call “index”). However, it would still work on tables that you might think is an array, but it’s actually not because either it has an index of 0 (which is not a property of arrays in Roblox), the indices missed numbers, or both.

So instead, the solution would be integrating @LucidBits’s code with checking if the table doesn’t have a 0th index and checking if the highest index of the array (table.maxn(array)) is the same number as the number of elements in the array (#array).

local function isArray(Table): boolean
	if typeof(Table) ~= "table" then
		return false
	end
	
	for key, _ in Table do
		if typeof(key) ~= "number" then
			return false
		end
	end
	
	if Table[0] ~= nil then
		return false
	end
	
	if #Table ~= table.maxn(Table) then
		return false
	end

	return true
end

Then it isn’t an array. It’s just a table, and can be modified - a bit like a list in Python, or a DVA in c-based. Arrays have a fixed length, and cannot be modified; this is possible in Roblox using table.freeze. This is similar to how dictionaries have string keys; they are still a type of table.



@LucidBits code would indeed work; I never denied it would. We just need @DanishXDCPA to mark it as solution.



It had just got me thinking about how Luau is very different to other languages, and you could indeed replicate standard array behaviour, blocking table.insert() and table.remove(). This would make the checking process a lot simpler.

local array = {
    [0] = "Something", --manually set first index to 0
    [1] = "Something else"
}

--__newindex to stop number indexing
array.__newindex = function(tbl, key, value) warn("New indexes are not allowed in array.") end

--table.freeze to stop the table functions
table.freeze(array)

--then just use table.isfrozen
if table.isfrozen(array) then
    print("It is an array")
end

Like I said above, some things cannot be done in Lua but a very similar alternative can be created to produce an almost identical effect.



Why would you need setmetatable to set metamethods? All setmetatable does is cause one table to inherit everything from another.

In Roblox, arrays and dictionaries are types of tables. Their only difference is their keys: dictionaries can have any type as a key, while arrays only have integers as the keys (and must be strictly counting from 1, without gaps). If you don’t believe me, check this.

As stated in the same webpage, unlike other programming languages, arrays in Luau starts with [1] instead of [0].

If you check the documentation about Metatables, you can see that the metamethods are put in the metastable then in order for the metamethods to take effect in a table, the metastable containing the metamethods are connected with the desired table using setmetatable().

I’m going to be honest. Roblox documentation is… not always the best. I myself would not necessarily treat it as a “reliable source”, but more guidelines that are taken and modified. Some of it is great, some of it is… not. The metatable documentation you just talked about may be a good example of this, because simply assigning a metamethod as a property works just as well, maybe in fact better considering you can only have one metatable for a table and that may get in the way. Metatables just add to properties, which is why they are used for mock-OOP - so the new object inherits from the class.

Like I said above, Luau is different to other languages. I think we may be confused; I am attempting to relate to the conventional array in programming - fixed length, 0 index, locked, all elements the same data type. You are referring to a different type of array.

idk if i can still hold my anger… i don’t want to be angry and mean but i also don’t want this anger to stay in my chest…

why is Roblox documentation not a “reliable source” when it’s made by the official Roblox staff and it exists for almost as long as Roblox? what you showed earlier just creates a new property in the table array with the key "__newindex". i also tried your code in Roblox Studio and it doesn’t work just as well??? where the hell did you get that info??? metatables doesn’t just add properties, they also store the desired metamethods that you want to take effect in the desired table that you want to set the metatable to

also you’re the only one confused. the conventional array you’re talking about is NOT the array in Luau (Roblox’s version of Lua 5.1)

I just mean the conventions they use sometimes are not the best. Don’t get me wrong, some of it is really good. I just begin to question things when, for instance, I see full caps variable names and pairs iterator on a GetChildren table.

Huh well that’s odd becuase I tested it and it worked fine

What do you have against assigning a metamethod as a property? Different people have different preferences. If you want to use a metatable, go ahead. I dont because Itend to use modules mainly for OOP, and use other tables for metatables. Tables used outside don’t require metamethods.

Exactly what I just said.

idk why ur so annoyed. We are just having a disagreement because we are talking about different things. I know Luau is different, I already said that. There is no need for rage. We are beginning to get off topic now.

what the hell

because IT. DOESNT. WORK. you must set it as a property in a metatable so that it doesn’t work

the way you’re applying things from other programming languages is NOT helpful. only follow luau, otherwise it wont work

just tested again and it worked

Look. I already said above that arrays are different in Luau. I also said that it got me wondering how you could replicate array behaviour in Luau. I did not ever say that I was completely right and you were completely wrong. We are discussing.

keyword replicate

Please stop, we are going off topic.

i dont think the op meant the array you meant to because WE’RE in roblox

Which is why I said @LucidBits 's solution would work and then explicitely said how I wondered how someone would go about making an array here act like a standard array, providing ideas. You then came and told me I was wrong, because you took my idea about array behaviour as an answer to the topic. You should next time read the topic before replying.

Please do not reply to this post.