How to code/create tables/dictionaries with key names that are not hard coded (supplied by user)

Im sorry, this doesnt make a whole lot of sense, but I am going to try to explain it.

So pretty much, I want to save some data in a table. The data is a list of user IDs, and each user ID will be the key for a list of tags, and each tag will have a number attributed to it. Like this:

Template:
data = {
    [userId] = {
        [tag] = 0
        [tag] = 0
        [tag] = 0
    }
}
Example:
data = {
    [4836512632] = {
        ["abc"] = 10
        ["def"] = 5
        ["ghi"] = 2
    }
    [1682535474] = {
        ["abc"] = 24
        ["def"] = 1
        ["ghi"] = 9
    }
    [9634548525] = {
        ["abc"] = 6
        ["def"] = 92
        ["ghi"] = 12
    }
}

The problem is, I need my code to name the keys in the dictionary, so that a user can give me a list of tags and a user ID, and the code will create a new user ID table (shown in the template section) inside the main table (called data), with the word userId replaced by the user ID, and each of the words tag replaced by the tags given by the user (there may be more or less than 3).

I have no idea how to do that, it might be possible to use string formatting (that is what I tried) but I don’t know how to make it work. Is it even possible to change/create a dictionary key with code?

I tried this: (does not include a way to make it work with any number of tags)
tags = {"a", "b", "c"}

dataTemplate = {
	["%c"] = {
		["%s"] = 0,
		["%s"] = 0,
		["%s"] = 0
	}
}

data = {}

userId = 1234567890

table.insert(data, string.format(dataTemplate, userId, tags[1], tags[2], tags[3]))

print(repr(data)) --repr is a module that prints tables in a readable format (link below)

Repr – function for printing tables - Resources / Community Resources - DevForum | Roblox

The (first of many) problems is, I get an error because I cannot do string.format() on a table. The way to get around this would be to do string.format() on each of the dictionary keys, instead of on the table as a whole, but I dont think you can reference the keys in the code. I know you can change the values, but I dont think the keys.

So, because I don’t know how to change what the key is, I decided to change it to something like this:

tags = {"a", "b", "c"}

dataTemplate = {
	{"%c", "%s", "%s", "%s"} -- %c is for the userId, %s is for tags
}

data = {}

userId = 1234567890

table.insert(data, string.format(dataTemplate[1], userId, tags[1], tags[2], tags[3]))

print(repr(data))

This doesnt work, because again, I am giving string.format() a table.

To solve the problem of giving string.format() a table, I tried this as a test:

tags = {"a", "b", "c"}

dataTemplate = {

    {"%c"}

}

data = {}

userId = 1234567890

table.insert(data, string.format(dataTemplate[1][1], userId))

print(repr(data))

When I did what is in the dropdown above, I got this in my output: {"ďż˝"}. repr will print tables inside tables, so the ? isnt because it is being asked to print a table in a table. I confirmed this by doing print(repr(data[1])) and it gave me "ďż˝".

Any help would be greatly appreciated, and I understand if you don’t want to help, it is a lot of stuff to look through, and this is only the beginning of what I am trying to do. I really hope I explained it well enough, and please lmk if you need clarification. TYSM!

You want that with the player’s ID to access or create an especific table?

1 Like

I want it to add the user ID table (based off of the user ID section in the template) to the data table. I would then run this code when I want to create new data for a new user

If I understand this will help.

local data = {}

--add

local plr = ThePlayer
data[plr.UserId] = {
    ["abc"] = 1,
    ["def"] = 5,
    ["ghi"] = 0,
}

--get
local especificTable = data[plr.UserId]
print(especificTable.abc,especificTable.def, especificTable.ghi)

--output--
1, 5, 0

--rewrite

data[plr.UserId] = {
    ["First"] = 10,
    ["Hi"] = 2,
    ["Tag"] = 5,
}

especificTable = data[plr.UserId]
print(especificTable.First, especificTable.Hi, especificTable.Tag, especificTable.abc)

--output

10, 2, 5, nil

--delete

data[plr.UserId] = nil

especificTable = data[plr.UserId]
print(especificTable)

--output

nil
2 Likes

Ok tysm! I think that will work!

One question, if I wanted to change the tags based on the tags setup table, as opposed to having them hard coded in, could I do this?

tags = {"a", "b", "c"} -- set by user
data = {}

data[player.UserId] = {}

for count = 1, #tags do
    data[player.UserId][tags[count]] = 0
end

if I did this, would printing data[userid] output a = 0, b = 0, c = 0?

sorry I took so long to reply!

EDIT: I also just noticed you did table[key] in some cases and table.key in others. What is the difference?

Yes it will print that.

table["Hi"] = "Hello"
--This you can do this only with string
table.Hi
--You cant make this
table.100
--Thats why you need to make this:
table[100]

When you do something like table.player1 = 10, “player1” is implied as a string.
However when you do it like table[player1] = 10, “player1” is regarded as a direct reference and will be used as the key, so something like

local player1 = "yes"
table[player1] = true

will mean that table.yes == true, as well as table["yes"] == true (since it’s the same thing)

So table.hi works, and table["hi"] works? But table.100 doesnt work? And would table[100] give you the 100th item in the table or an item with the key 100?

Also ty @Locard for clarifying

table.hi and table[“hi”] works. table.100 dont work.

local tab = {1,2,3,4 ... 98, 99, 100}
The table is this:

{
    [1] = 1,
    [2] = 2,
    [3] = 3,
    ...
    [100] = 100,
}

print(tab[100]) -> will print the last item
local tab = {}
tab[100] = "Hi"
The table is this:

{
    [1] = nil,
    [2] = nil,
    [3] = nil,
    ...
    [100] = "Hi"
}

print(tab[100]) -> will print the last item
1 Like