How to use keys as strings without looping?

  1. What do you want to achieve?
    I want to be able to use a key as a string when calling the key. Is it possible to achieve this?

  2. What is the issue?
    I am looking to see if I can further reduced my module script without the need to create another key to store the key’s string. It would look something like this

local classes = {
     ["Flanker"] = {
          ["Name"] = "Flanker", -- I wonder if there's a way to not need to make this key.
          ["Attributes"] = ...,
          ["Description"] = ...,
     }
}
  1. What solutions have you tried so far?
    There are two solutions I am aware of. One is through the method of using in pair loop to retrieve the key, but I want to directly retrieve that key. Another solution is to create another value as “Name” and give it the value as a string.
-- Here is a sample module script:

local classes = {
     ["Flanker"] = {
          ["Attributes"] = ...,
          ["Description"] = ...,
     },
     ["Shotgunner"] = {
          ["Attributes"] = ...,
          ["Description"] = ...,
     },
}

-- What I want to do with this:

-- main class function
-- assume that player.ClassSelected is a string value
if player.ClassSelected.Value == classes.Flanker then
     -- do flanker things
end

The reason I am looking for this kind of system is to use Roblox’s Intellisense/autocomplete system throughout my programming journey. Another reason is that there might be 100+ items under the module where it maybe a hassle to have another key under the main key that only stores the name of the key’s string.

3 Likes

??

if player.ClassSelected.Value == "Flanker" then
    local class = classes.Flanker
     -- do flanker things
end
1 Like

Keys are automatically strings when you just use text as a key in a dictionary.

local dict = {
	YourKey = YourValue
}

is the same as

local dict = {
	["YourKey"] = YourValue
}

You would call both the same way, dict.YourKey. The only times when a key isn’t automatically text is when the key is a number, Vector3, etc.

Maybe I should have further explained why I would want to do this, in case there was ever a chance I have over 100+ classes, I would not want to remember all 100, especially if the names are specific. In this case, I want to be able to easily call classes.Flanker as a string for convenience.

So if I set my StringValue == dict.YourKey, which “YourKey” is presented as a key string, I should be able to set the value as “YourKey”? Just to reiterate that I have multiple values under dict.YourKey as shown above.

You can set dict.YourKey to whatever value you want. If you want to set multiple values under the key, then you have to put them in a table

dict.YourKey = {2, 4, "Text", false}

In the example code, dict.YourKey represents an array, so you can call whatever value you want from the key by doing this.

print(dict.YourKey[3]) -- Ouput: Text

I could do this, but it’d be inconvenient for me as I have to remember the position of where the string is going to be. A better method which I have is

module = {
     ["Flanker"] = {
          ["Name"] = "Flanker",
          ["Attributes"] = ...
     }
}

However this doesn’t solve my problem. I want to use “Flanker” from the key to be use as a string which I am hoping this will reduce the need of making a [“Name”] key.

Many ways to do this but, you never stated where the string class is being stored as in “flanker”
Then with that string you can find/change whatever data is in the table by that string.
Is this in the player Name or a Attribute

character:SetAttribute("Class", "Flanker")

-- Get the attribute value
local attributeValue = character:GetAttribute("Class")
if attributeValue == "Flanker" then
   print(["Flanker"]["Description"])
end

I don’t think I would want to change the values inside classes[“Flanker”] to “pin” as I have other values inside that I am keeping track of. I want to be able to use “Flanker” as a string from the key’s name.

I still don’t get what your problem is. If you already know the key is Flanker, then you don’t have to reference the dictionary.

Well, I know that the key is Flanker, however I have replied to @a19_9 of why I want this kind of system.

Maybe I should have further explained why I would want to do this, in case there was ever a chance I have over 100+ classes, I would not want to remember all 100, especially if the names are specific. In this case, I want to be able to easily call classes.Flanker as a string for convenience.

If anything I will use this system where I need to reference to name to get “Flanker”, but I’d like to see if the current problem I proposed has a possible solution.

module = {
     ["Flanker"] = {
          ["Name"] = "Flanker",
          ["Attributes"] = ...
     }
}
local name = module.Flanker.Name

The only use that I can think of for wanting to use the key is in a for loop, which you’d just do this.

for key, value do
	print(key, value)
end

-- Output: Flanker, ...
1 Like

I have mentioned this is a possible solution, the problem is that it would have to access many values before it reaches the target key. The worst case scenario is if the key is at the very last index.

Code runs pretty fast, but if that’s what you feel comfortable using, then I’ll respect that.

Are you talking about this?

local Table = {
	Value = 1
}

print(Table["Value"]) -- 1

Dot syntax is the syntax sugar for this, not the other way around. When you do module.Flanker.Name, that is basically the same as module["Flanker"]["Name"].

It’s kind of hard to understand what you are precisely asking for since you are using a weird description of the problem and what you want to achieve.

So you essentially want to be able to store Class data/metadata under easily referenced values? i.e player.ClassSelected?

I understand that module.Flanker.Name and module["Flanker"]["Name"] are the same. What I wanted to get from this is simply calling module.Flanker so I can use “Flanker” as a string… if that make sense. Knowing that calling module.Flanker would return some table/dictionary value, I was wondering if I can get the key’s string and compare that string with anything else. In other words, I want to do something like this:

module = {
     ["Flanker"] = someValue
}

local className = module.Flanker -- using "Flanker" as some string

Yes, precisely. I have other values stored under the key, but I want to see if it is possible to get the key’s string and store that value without the need to create an additional key to store the key’s string

OHH you want to get the Index string, okay. To do that, you really only have one option, well, two, but only one really makes sense.

Just add a ClassName variable to the data. Otherwise, you could do a for loop and reference the data match to get the index.

local Data = {
  ["Test"] = {
    ["Attributes"] = {["Damage"] = 12, ["Weapon"] = "Sword"},
    ["Description"] = "A Test data insert"
  }
}

local PlayersClass = Data.Test

local function GetClassName(ClassData)
  for ClassName, Compare in pairs(Data) do
    if Compare == ClassData then
      return ClassName
    end
  end
  return "None"
end

print(GetClassName(PlayersClass))

@Corruptonator have mentioned this solution, but as said before, I like to utilize my code by making it run as quickly as possible. If this is the only solution however, I might stick to adding an additional key for “Name”. Thought I guess it would run pretty fast as it is a linear search.