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

Values as indices and not just strings or integers and other Lua questions?

Today I was reading the Lua 5.2 Reference Manual and it stated, "The type table implements associative arrays, that is, arrays that can be indexed not only with numbers, but with any Lua value except nil and NaN." Interested, I went onto studio to test this idea:

local key = {true, false, nil}
local array = {}
array[key] = "Hello World!"
print(array[key])
local secondKey = true
array[secondKey] = "Goodbye World!"
print(array[secondKey])
local dictionary = {
	[key] = "Test one.";
	[secondKey] = "Test two.";
}
print(dictionary[key])
print(dictionary[secondKey])
print(array.key, array.secondKey, dictionary.key, dictionary.secondKey)

Only afterwords I realized that array.key was equivalent to array["key"] and of course there was no value at the index of "key". However, the other prints were what I was really interested in. The output looked like this: Hello World! Goodbye World! Test one. Test two. nil nil nil nil Wow, it all worked(except the nils but I know why those are). I am now curious what an associative array is. Also, what kind of uses does this have? All I can think of is accessing a value that needs multiple keys to be accessed. As for the Boolean tests those were not as important. I mean, there are only two Boolean values, so it might be a little difficult to use them effectively in a large table. After reading down a few lines I saw that, "Like indices, the values of table fields can be of any type. In particular, because functions are first-class values, table fields can contain functions. Thus tables can also carry methods." I knew that functions could be in tables, but I am curious as to what field means. I have seen it many times and should know it by now, especially because many errors deal with fields. Further down the page it said, "The expressions a[i] and a[j] denote the same table element if and only if i and j are raw equal (that is, equal without metamethods)." I am not entirely sure what raw equal means in this instance. Finally, I was reading this, "Tables, functions, threads, and (full) userdata values are objects: variables do not actually contain the values, only references to them. Assignment, parameter passing, and function returns always manipulate references to such values; these operations do not imply any kind of copy." So, I went ahead and did a test:

local a = {"Unchanged","Unchanged", "Unchanged", "Unchanged", "Unchanged"}
local b = a
for i = 1, 5 do
	a[i] = "Changed"
	print(b[i])
end
for i = 1, 5 do
	b[i] = "Changed2"
	print(a[i])
end

The output was: Changed (x5) Changed2 (x5) I am curious if there is an easier way to assign a and b at the beginning, but that is not the main focus of this question. I am wondering if there is a way to copy the table/function/threads/(full) userdata values instead of referencing them which may not be the best if both sides(by that I mean both a and b) can change the original list, which may cause some unknown bugs to happen because it does not throw an error. All because the code is all syntactically correct, just not logically correct.

1 comment

2

u simply cant

1 answer

✓ Accepted answer

#Associative Arrays and Keys

An associative array is the abstract data model composed of a collection of key-value pairs. In Lua, these are implemented as tables.

One way of thinking about keys to tables are literal keys that map to a certain value. It's called an associative array because it associates values together. For example, if parts in workspace were associated with certain values (for whatever reason), it could be stored in a table like this:

{
	[workspace.Part] = 2;
	[workspace.AnotherPart] = 4;
	[workspace.Part2] = 3;
}

With this, you can conveniently access the value associated with each part. You may wonder why you can't just do something like this:

{
	[2] = workspace.Part;
	[4] = workspace.AnotherPart;
	[3] = workspace.Part2;
};

First, notice that all keys and indices must be unique, and consequently, no two parts can be associated with the same integer. However more importantly, we cannot access the integer of a part directly. With the first example, we would simply have to do tbl[part] in order to access its value. However with the second, we would have to do something like this:

for i , v in pairs(tbl) do
	if v == part then
		print(i)
	end
end

That looks an order of magnitude more ugly but also requires more running time as it must iterate through all elements of the table whereas the first example can look up the part in a constant amount of time (most of the time it's constant).

Copying Userdata and Referenced Objects

For the most part (with the exception of tables and Roblox instances), making a copy of a referenced object is trivial because they're immutable. Functions, for example, cannot be changed in any way, so making a carbon copy of one is useless. Technically, you can clone a function by using string.dump() and loadstring() but I'm not even going to go there since you shouldn't be doing things like that anyway. Strings are also immutable and are in fact passed by reference as well. As for copying tables, you can make a shallow copy of one by using a for loop:

for i , v in pairs(tbl) do
	copy[i] = v
end

You can make a deep copy by recursively copying all the elements of the table itself as well.

I hope that answers all of your questions. Good luck!

3 comments

0

I actually have one additional question I forgot to mention in the original question. Because of the way tables work in Lua does that mean that a dictionary is not different than a table like it is in Python(with key value pairs)? Because you can index with any value except the ones I mentioned that would make a dictionary and a table the same thing right?

0

Oh, and are there no Lua methods to copy a table or something?

0

If you do t2 = t1 you're making a reference to t1. To simply copy a table you could do {unpack(t)}

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