Key values and indexing

I looked around, but because of the terms involved in the search, I can’t seem to narrow down an answer. As you can tell, I’m new to Lua.

Given a key value array like this:

local sheetData = {foo="a", bar="b"}

is this:

sheetData["foo"]

the same as:

sheetData[1]

I’m poulating a table with names for a function and I’d also like to reference the data using an index so I can choose a random one from the arrary.

nope, this is not the same

local tableWithIndexes = { "a", "b", "c" } print(tableWithIndexes[1]) -- will print "a" local tableWithKeys = { foo = "k", bar = "n" } print(tableWithKeys.foo) -- will print "k" print(tableWithKeys["foo"]) -- will also print "k"

To iterate through indexed table you use

for i = 1, #tableWithIndexes do print(tableWithIndexes[i]) end

or like this (but first one is more effective in Lua

for k, v in ipairs(tableWithIndexes) do print(v) -- k will be 1, 2, 3 ... end

As for key/value pairs - you can only use second type of iteration because such tables have no order (they are not indexed, so even if tableWithKeys[1] returns you some element of table then there is no sure that it will be “foo”)

for k, v in pairs(tableWithKeys) do print(k, v) -- will print (foo/k and bar/n) or (bar/n and foo/k) end

Lua is different from other languages in that it unifies dictionaries and arrays.

In many languages, there is an object called a dictionary. It’s a set with each member identifiable by (usually) a string. So with a dictionary, you do things like:

[lua]

myDict.this = 50

– or –

myDict[“this”] = 50

[/lua]

Just about every language also has a set called an array. They’re much like dictionaries, but they use numbers instead of strings. Like so:

[lua]

myArray[1] = 5

[/lua]

This is where Lua is different. Lua creates one data storage object, called a table, that can store things under any index type. So with Lua, you can use tables as keys, booleans as keys, even functions as keys - in addition to numbers and strings.

When indexing a table through [key], it will return whatever is stored under that key. Each key is unique - numbers, strings, functions, booleans, threads, userdata, table, what-have-you. Declaring a table without naming keys - {“a”, “b”, “c”} - turns into {[1] = “a”, [2] = “b”, [3] = “c”}. Thus, they’re not the same.

  • C

Thanks for the info everyone.

So it sounds like I can’t use a numeric key to access table elements. It looks like I have to step through the array/table to get to what I want.

Since a variable can be used as an index, can I setup another “regular” array with the keys and use it to reference entries in the table?

For example:

local tableWithKeys = { foo = "k", bar = "n" } local myIndexArray = {"foo", "bar"} local myKey = 1 print(tableWithKeys[myIndexArray[myKey]]) -- will this print "k"?

That way, I can use a number to reference the items in the table while still using the original table for other areas that need to reference by the key. And I wouldn’t need to step through the table as in earlier suggestions.

Thoughts?

Yes, will print :stuck_out_tongue:

but will it print “k”?

:wink:

Try it :slight_smile:

  • C

Yep, it worked. Just curious if this is “supported” way to do it. I’m trying to avoid any nuance in the language.

It gave me the right results, so I’ll assume I’m good to go.

Thanks everyone!

Most welcome :slight_smile:

  • C

nope, this is not the same

local tableWithIndexes = { "a", "b", "c" } print(tableWithIndexes[1]) -- will print "a" local tableWithKeys = { foo = "k", bar = "n" } print(tableWithKeys.foo) -- will print "k" print(tableWithKeys["foo"]) -- will also print "k"

To iterate through indexed table you use

for i = 1, #tableWithIndexes do print(tableWithIndexes[i]) end

or like this (but first one is more effective in Lua

for k, v in ipairs(tableWithIndexes) do print(v) -- k will be 1, 2, 3 ... end

As for key/value pairs - you can only use second type of iteration because such tables have no order (they are not indexed, so even if tableWithKeys[1] returns you some element of table then there is no sure that it will be “foo”)

for k, v in pairs(tableWithKeys) do print(k, v) -- will print (foo/k and bar/n) or (bar/n and foo/k) end

Lua is different from other languages in that it unifies dictionaries and arrays.

In many languages, there is an object called a dictionary. It’s a set with each member identifiable by (usually) a string. So with a dictionary, you do things like:

[lua]

myDict.this = 50

– or –

myDict[“this”] = 50

[/lua]

Just about every language also has a set called an array. They’re much like dictionaries, but they use numbers instead of strings. Like so:

[lua]

myArray[1] = 5

[/lua]

This is where Lua is different. Lua creates one data storage object, called a table, that can store things under any index type. So with Lua, you can use tables as keys, booleans as keys, even functions as keys - in addition to numbers and strings.

When indexing a table through [key], it will return whatever is stored under that key. Each key is unique - numbers, strings, functions, booleans, threads, userdata, table, what-have-you. Declaring a table without naming keys - {“a”, “b”, “c”} - turns into {[1] = “a”, [2] = “b”, [3] = “c”}. Thus, they’re not the same.

  • C

Thanks for the info everyone.

So it sounds like I can’t use a numeric key to access table elements. It looks like I have to step through the array/table to get to what I want.

Since a variable can be used as an index, can I setup another “regular” array with the keys and use it to reference entries in the table?

For example:

local tableWithKeys = { foo = "k", bar = "n" } local myIndexArray = {"foo", "bar"} local myKey = 1 print(tableWithKeys[myIndexArray[myKey]]) -- will this print "k"?

That way, I can use a number to reference the items in the table while still using the original table for other areas that need to reference by the key. And I wouldn’t need to step through the table as in earlier suggestions.

Thoughts?

Yes, will print :stuck_out_tongue:

but will it print “k”?

:wink:

Try it :slight_smile:

  • C

Yep, it worked. Just curious if this is “supported” way to do it. I’m trying to avoid any nuance in the language.

It gave me the right results, so I’ll assume I’m good to go.

Thanks everyone!