Okay so, I'm trying to take an input and decode it into a table of numbers and strings an example of an input is
"Weapon:Starter Sword:A basic starter sword:none:ohls:5:45:100:0"
The code to decode and encode is:
local m = {} local player = game.Players.LocalPlayer function m.Decode(string) local inventory = {} local currentposition = 1 local currentstring = "" for i = 1, string.len(string) do if not string.sub(string, i) == ":" then currentstring = currentstring..string.sub(string, i, i + 1) else table.insert(inventory, currentposition, currentstring) currentstring = "" currentposition = currentposition + 1 end end return inventory end function m.Encode(table) --takes the string that was decoded from the table above^ local string = "" for i = 1, #table do if i == #table then string = string..table[i] else string = string..table[i]..':' end end return string end --Weapon:Starter~Sword:A~basic~starter~sword:none:ohls:5:45:100:0 return m
It takes all the strings between the ':'s and adds them to a table. I also need it to check if the number in a string is a number and make it a number value instead of a string value.
Looks like you need to really get to know the string.gmatch
function(:
The string.gmatch function actually returns an iterator function.. and each time said function is called then it will return any string in the first argument(the string you're 'gmatching') that matches the pattern in the second argument(the pattern you want to 'gmatch').
So, because this returns an iterator function.. can you think of any loops that take in iterator functions? The generic for loop! The syntax for the generic for loop is;
for [values] in [iterator function] do
Since the string.gmatch function only returns 1 value(the matching string) then you only need 1 variable in the '[values]' spot. This variable will hold whatever potential string match, from within the given string, that would match the given pattern.
So I keep talking about 'given string' and 'given pattern' right? What the heck am I talking about?
The string.gmatch function takes in 2 arguments!
1 ~ The string to match
2 ~ The pattern to match the string
When I say "The pattern to match the string" then what i'm meaning is that there are literally syntax patterns to match strings with. There are various patterns.. %d gets numbers.. %a gets letters.. %u gets uppercase letters.. etc..
So String Patterns are literally used for defining patterns that you want to search for in a string. Just an example before we continue - if I wanted to get the letter 'G', then any lowercase letters after that, then i'd use the pattern 'G%l+'
. And an example of full usage;
--Pretty redundant statement.. this is just an example(; --This is the string you're going to match local str = 'Goulstem is so Cool, Goul is God' --This is the pattern you'll be matching with local pattern = 'G%l+' --Use the generic for loop, with string.gmatch iterator function. for i in string.gmatch(str,pattern) do print(i) end --[[Output]]-- --Goulstem --Goul -- God
As you can see, the code printed the three texts.. because those three string of characters matched the given pattern!
So, now that i've sort of walked you through basic understanding of the string.gmatch function and how string patterns operate.. then I think you're ready for the main lesson.
You need to use :%w+
as a pattern.. to find any alphanumeric in the string(uppercase, lowercase, or diget) after a colon. This way, you can capture everything in between the colons. But there's some more to it.. with this pattern then it also captures the colon! So you have to use the string.sub
function to seclude the colon from the string capture(:
Once you get the string returned from this pattern then you need to check if it's a number, or a bool.. if it's either or then you need to insert it into a separate table as said datatype.. otherwise keep it a string.
local m = {} m.Decode = function(str) --Predefine table local tab = {} --Predefine string pattern local pattern = ':%w+' --Generic for loop to iterate through string for i in string.gmatch(str,pattern) do --Limit capture i = i:sub(2) --Check if it's a bool if i == 'true' then table.insert(tab,true) elseif i == 'false' then table.insert(tab,false) --Check if it's a number elseif tonumber(i) ~= nil then table.insert(tab,tonumber(i)) --Otherwise, keep it a string else table.insert(tab,i) end end --Return decrypted table return tab end --Your Encrypt function was fine. --[[ Usage: local str = ':Hi:2:true:Lol' local tab = m.Decode(str) for i,v in pairs(tab) do print(v) end --> Hi --> 2 --> true --> Lol ]]--
You could use the tonumber() function to check if the current string made into a number doesn't equal nil and then add that number (from using tonumber()) to the table if it doesn't equal nil. Otherwise, just add the string in normally.
For example, if you had "50" and used the tonumber() function on it, it would return 50 as a number, as opposed to using the tonumber() function on "Sword", which would return nil since sword is not a number.
So, for your decoding function, you can do this:
function m.Decode(string) local inventory = {} local currentposition = 1 local currentstring = "" for i = 1, string.len(string) do if not string.sub(string, i) == ":" then currentstring = currentstring..string.sub(string, i, i + 1) else if tonumber(currentstring) ~= nil then --Checks if the string converted to a number returns an actual number. table.insert(inventory, currentposition, tonumber(currentstring)) --Adds the string converted to a number into the table, it would just add in the string if you didn't do this, which is not what you want. else table.insert(inventory, currentposition, currentstring) end currentstring = "" currentposition = currentposition + 1 end end return inventory end
You don't need to do anything for the encoding function though as numbers are automatically made into strings when they is used in string concatenation
.
I hope this helped you. If it did, be sure to accept it.