join two string to one table in Lua - lua

I have 2 strings:
fields="a,b,c,d,e"
values="1,2,,4,5"
I need a table, to get the pairs values like:
print(result.a) -> "1"
print(result.c) -> "" (or nil)
Is it possible?

Here is an opportunity to exploit generators without a for loop. The code below runs two gmatch generators in tandem.
fields="a,b,c,d,e"
values="1,2,,4,5"
fields=fields.."," ; F=fields:gmatch("(.-),")
values=values.."," ; V=values:gmatch("(.-),")
result={}
while true do
local k,v=F(),V()
if k==nil or v==nil then break end
result[k]=v
end
for k,v in pairs(result) do print(k,v) end

Related

Does such an encryption/cipher method exist?

while thinking of an idea to create an encryption/cipher method, I thought of one that I wondered existed already. The method I imagined was to have pre-set characters, but instead, randomly generate meanings for these characters.
Here's what I mean: (Representation in Lua)
local Keys = {'a','b','c',} -- Rest of table removed for simplicity
for i,v in pairs(Keys) do
Keys[v] = ''
repeat
if Key[v] then
Keys[v] = Keys .. string.char(math.random(1,255))
else
Keys[v] = string.char(math.random(1,255))
end
until string.len(Keys[v]) == 4
end
print(Keys) --> {'a' = "ą�vź",..}
Then when you make a string and transcribe it with the Keys table, it'll come out as the meaning given to it. Pretty simple, could probably do more with it, but does something like this already exist (have an official name for the method, perhaps?)
Passwordless obfuscating is also done with ROT.
Just for fun i do this...
-- rot.lua
-- Usage: Creates a table (i.e. rot) for using it with string.gsub('Hello World','(.)',rot)
-- A '.' in gsub() is neccessary to hit every single char in a string
-- ROT13 for chars, ROT5 for numbers, ROT8/ROT3/ROT2/ROT1 for signs
-- IMPORTANT: Both key/value pairs has to be datatype string
local args={...}
local rotator=function(...)
local args, rot, c ={...}, {}, ''
-- ROT5 for numbers
for i=48,52 do rot[c.char(i)]=c.char(i+5) end
for i=53,57 do rot[c.char(i)]=c.char(i-5) end
-- ROT13 for chars (upper and lower case)
-- Uppercase letters (ROT13)
for i=65,77 do rot[c.char(i)]=c.char(i+13) end
for i=78,90 do rot[c.char(i)]=c.char(i-13) end
-- Lowercase letters (ROT13)
for i=97,109 do rot[c.char(i)]=c.char(i+13) end
for i=110,122 do rot[c.char(i)]=c.char(i-13) end
-- Signs (ROT8)
for i=32,39 do rot[c.char(i)]=c.char(i+8) end
for i=40,47 do rot[c.char(i)]=c.char(i-8) end
-- Signs (ROT3)
for i=58,60 do rot[c.char(i)]=c.char(i+3) end
for i=61,63 do rot[c.char(i)]=c.char(i-3) end
-- Signs (ROT2)
for i=91,92 do rot[c.char(i)]=c.char(i+2) end
for i=93,94 do rot[c.char(i)]=c.char(i-2) end
-- Sign # and tabstop (ROT1)
rot['\t']='#'
rot['#']='\t'
return args[1]:gsub('.',rot),rot
end
local _,rot=rotator('koyaanisqatsi') -- Extracting the rot table from function rotator
if #args==2 and args[2]==':preload:' then
table.insert(rot,rotator)
return rot
else
return rotator
end -- Conditional return when required and package.preload is triggered
If required und furthermore in string table as: string.rot you can obfuscating and deobfuscating with the same function...
> myvar='koyaanisqatsi'
> print(myvar)
koyaanisqatsi
> myvar=myvar:rot()
> print(myvar)
xblnnavfdngfv
> myvar=myvar:rot()
> print(myvar)
koyaanisqatsi

How to create a table of unique strings in Lua?

I'm trying to create a function that adds unique string to a table. I also wonder how to print the result.
My Code :
local t = {}
function addUniqueString(str)
--what should be here?
end
function printElements()
--what should be here?
end
addUniqueString("apple")
addUniqueString("orange")
addUniqueString("banana")
addUniqueString("apple")
printElements()
The Result I want : (order doesn't matter)
apple
orange
banana
Since the order doesn't matter, you can just add strings as keys to the table:
local t = {}
function addUniqueString(str)
t[str] = true
end
And to list the strings:
function printElements()
for k in pairs(t) do
print(k)
end
end

Lua string comparison failing

I am trying to group entries in a csv file into different tables in Lua, based on the last attribute. But for some reason the string comparison doesn't work. The following is the code:
trainer = {}
tester = {}
valer = {}
for line in io.lines(mlist) do
local split = {}
for token in string.gmatch(line, '([^,]+)') do
table.insert(split, token)
if token == 'val' then
print('heelo')
end
end
if split[5] == "val" then
print('hello world')
end
if split[5] == 'test' then
table.insert(tester, split[1])
elseif split[5] == 'train' then
table.insert(trainer, split[1])
elseif (split[5] == 'val') then
print('hello')
table.insert(valer, split[1])
end
end
The file mlist contains the following entries (It actually has a lot of records, but I am putting a few for testing):
050810,02747177,02747177,a2e9d8324c1f62cd5ecea499ceee624d,train
051087,02747177,02747177,89aff0d006fc22ff9405d3391cbdb79b,train
051145,02747177,02747177,c6ef918f335bb21c5896bab37ddebe7,train
051416,02747177,02747177,ec1c1aa7003cf68d49e6f7df978f3373,train
051506,02747177,02747177,a8b39c32604173c1d2b12aa6a0f050b3,train
051654,02747177,02747177,e3484284e1f301077d9a3c398c7b4709,train
001174,02747177,02747177,bf4dd114b53bd8f0d67352166d8df9fd,val
003009,02747177,02747177,2f1aed8925147120c62ac18334863d36,val
003735,02747177,02747177,c3b31dc8c48265ecfffc97a61124b1a9,val
004213,02747177,02747177,3a982b20a1c8ebf487b2ae2815c9,val
005241,02747177,02747177,91a4d060d380409c2056b4bd5d870b47,val
008467,02747177,02747177,4d6b6d392ec6b5b4c69692992c7aeb,val
008652,02747177,02747177,3be3e86b2fad511048d5a1386787189,val
008659,02747177,02747177,1e1015a06e43c0a5a44b6af22454453b,val
010510,02747177,02747177,62f4ed6e1df63042cecaed25e0da0964,val
013730,02747177,02747177,7069760a16db98f46c9e5b09a1c294d9,val
016657,02747177,02747177,ae3257e7e0dca9a4fc8569054682bff9,val
018178,02747177,02747177,86194a4645da1f19e14ca01ae177e9d,val
019142,02747177,02747177,e5b7b5112e396a49b581cc9c4410f841,val
021424,02747177,02747177,4088f2056763a95752e986a5f722a6f,val
022098,02747177,02747177,b77e94ab409def2b72745b90f9692729,val
022185,02747177,02747177,b51812771e42354f9996a93ae0c9395c,val
027358,02747177,02747177,5092afb4be0a2f89950ab3eaa7fe7772,val
028916,02747177,02747177,63adebf24a1de9ecf91cc5a18046145f,val
031579,02747177,02747177,1c3cf618a6790f1021c6005997c63924,val
032507,02747177,02747177,dc7ce614dc719649b394cfa64dfabe8e,val
034010,02747177,02747177,6a1b359efc20cd1aaec6ee5ba573fa6d,val
035290,02747177,02747177,c904d927672acd48ad8a0ee9b106700e,val
036604,02747177,02747177,f116f3c432856fccddd8899c86e55073,val
039697,02747177,02747177,c21d8f5641be31a285cac25b72167160,val
040234,02747177,02747177,330cdd681a0890b190fdbeabcd02777c,val
041653,02747177,02747177,b838c5bc5241a44bf2f2371022475a36,val
044825,02747177,02747177,af6fa396b2869446d4d8765e3910f617,val
046115,02747177,02747177,1cb574d3f22f63ebd493bfe20f94b6ab,val
046248,02747177,02747177,942887c8d668501681faebbdea6bd9be,val
046853,02747177,02747177,92fa62263ad30506d2b12aa6a0f050b3,val
046957,02747177,02747177,c77e8499be0ce1e04f3443b22038d340,val
048064,02747177,02747177,c18e807ff9858a51fb016d9401ff3e29,val
048971,02747177,02747177,18dbebd6527cffa254685f5f473de41f,val
051563,02747177,02747177,7c90fba6cd7f73871c1ef519b9196b63,val
I checked the type of split[5] and it is indeed string. I even tried
print(split[5] == 'val')
which prints false.
Thanks for the help!
There is a simpler (more generic) way of splitting your lines into buckets according to the last 'key', without using a series of if blocks to catch every possible 'key'. Something like this (use input redirection to load the file in this example):
local groups = {}
for line in io.lines() do
v,k = line:match '^(%d+),%d+,%d+,%x+,(%w+)$'
if v ~= nil and k ~= nil then -- or, just if k
local t = groups[k]
if t == nil then t = { v } else t[#t+1] = v end
groups[k] = t
end
end
-- And, to see table contents for verification...
for k,v in pairs(groups) do
print(k)
for i,v in ipairs(v) do print('',i,v) end
end
UPDATE/SOLUTION:
Thanks to the solution of Egor Skriptunoff in the comments, this has been solved. The problem is on Linux the CR and LF are interpreted differently, and I was indeed using a file made on Windows on Linux. So just ignoring the last character in every line solves it. According to Egor's solution modifying the inner for that is splitting with this works:
for token in line:gsub('\r', ''):gmatch('[^,]+') do
....
end
Thanks again to Egor for the solution and the explanation!

calling config param from another function (concatenate global error)

local otherteam = {}
function onLoad()
...
Config.aaRange.enemyrange:addParam("enemy0", otherteam[0], SCRIPT_PARAM_ONOFF, false)
Config.aaRange.enemyrange:addParam("enemy1", otherteam[1], SCRIPT_PARAM_ONOFF, false)
Config.aaRange.enemyrange:addParam("enemy2", otherteam[2], SCRIPT_PARAM_ONOFF, false)
end
function onDraw()
...
for k = 0, 3, 1 then
if hero.charName == otherteam[k] then
if (Config.aaRange.enemyrange."enemy" .. k) then
...
end
end
end
end
I get Attempt to concatenate global enemy error while running this.
I can easily fix this by just removing the for k loop and having seperate if statements with
if (Config.aaRange.enemyrange.enemy0) then
end
if (Config.aaRange.enemyrange.enemy0) then
end
if (Config.aaRange.enemyrange.enemy0) then
end
But that just seems messy (I got more than 3 configs). I even tried:
j = "enemy" .. k
and adding j instead of enemy0 in the if statement but nothing.
I'm guessing this is because I'm trying to add the string with a number? Sorry, only started using lua a few hours ago :x
Lua supports coercion, so adding a string to a number is valid. But if you write
j = "enemy" .. k
The interpreter takes Config.aaRange.enemyrange.j as Config.aaRange.enemyrange["j"], you should use Config.aaRange.enemyrange[j] instead.
Without another variable, you can write
if Config.aaRange.enemyrange["enemy" .. k] then
Or better:
if Config.aaRange.enemyrange["enemy" .. tostring(k)] then

Lua, Tables: merge values of duplicate keys and remove duplicates

I've started fiddling a lot with lua recently, but I can't for my life figure this out.
Let's say I have a string that looks like this:
s = "a=x a=y b=z a=x"
I want to remove all duplicates and merge the values of duplicate keys into a table, so that I get:
t = {
a = {x,y},
b = {z},
}
I've been pondering about this for way too long. Any help is appreciated!
Try this:
s="a=x a=y b=z a=x"
s=s.." "
t={}
for k,v in s:gmatch("(.-)=(.-)%s+") do
if t[k]==nil then t[k]={} end
t[k][v]=true
end
for k,v in pairs(t) do
for z in pairs(v) do print(k,z) end
end

Resources