3

I am attempting to create a table to serve as a small database for users:

users = {}

function create_new_user()
    print("Enter a unique user name (up to 12 letters): ")
    local name = io.read()
    if #name > 12 then 
        print ("That name is too long.")
        return create_new_user()
    elseif users[name] then
        print ("That name is already in use.")
        return create_new_user()
    else
        table.insert(users, 1, name)    
        print("Your new user name is: ", users[name])
    end
end

I understood from the manual that the line

table.insert(users, 1, name)

would insert the string value of name as an element of the users array. This is not the case-- whenever I run the script I get the following output:

Your new user name is:   nil

2 Answers 2

5

You insert the element into the table, but you are trying to retrieve the value indexed by the value of name, which is not what you stored (you are using users[name] instead of users[1]). You can probably do something like this:

table.insert(users, name)
print("Your new user name is: ", name)

Note that table.insert(users, 1, name) may not do what you expect as this will prepend elements to the table. If you insert "abc" and "def" this way, then the users table will include elements {"def", "abc"} (in this particular order). To retrieve the last inserted element you can use users[1].

If you want to store values in a different order, you need to use table.insert(users, name), which will append elements to the table. To retrieve the last element you can use users[#users].

If you always want to store the added element in the first position in the table, then you can simply use users[1] = name.

Sign up to request clarification or add additional context in comments.

4 Comments

This works great-- I used table.insert(users, name) to push the new element, and users[#users] to pop it. But how do I check to see if a user name is in use? if user[name] doesn't seem to work for this purpose, do I need to iterate over all elements, or is there a built in function for this?
@etothepowerofx You'd have to do a linear search of the array. Much simpler (and more efficient, not that it matters here) to use the name as a key, as shown in my answer, so that your search is just a hashtable lookup.
@etothepowerofx, as Mud said, you can simply keep track of existing users in the same table using it as hashtable; when you added a new users, also store users[name] = true and when you removed (poped) a user, also remove it from the hash part (users[name] = nil). This way you can always use users[name] to quickly check if you have the user or not.
@Mud Thanks to you both, your answers were equally helpful. I've determined it's best to approach this as a table rather than an array based on your recommendation. I chose this as my answer because it was first.
3

Here you index the user table with a string (the name):

 elseif users[name] then

You do the same here:

 print("Your new user name is: ", users[name])

But you store the name with a numerical index:

 table.insert(users, 1, name)    

What you want instead of that line is:

users[name] = name

Or this (which would require changing the line that follows):

users[name] = true

The idea is you're only really using the keys, to create a lookup table.

2 Comments

Would I be creating a name key/value pair by using users[name] = name, where both the key and the value are the name string?
Yes. You could really use anything want as the value, since you're not really using it (it just needs to be something other than nil or false for your name check to work). There's nothing preventing you from, say, using user[name] = {} and then using user[name].password = password, user[name].lastlogin = os.time(), so on and so forth.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.