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
I am getting Components, which are saved in tables(I use a special system for better memory effiency). Then i give them as parameters in a given function(with the unpack statement(I already checked it isnt the reason)). So far so good, I get the value that is saved in the Table. But if I change it the component in the table doesnt change value. So in short: I want to give the component by reference but I am giving it by value. I thought Lua always gives values stored in tables by reference. Any help would be appreciated. If you need any additional resources just ask :). Thankyou in advance
function pool:run(dt)-- runs all active systems
local sprite = self.img
for i, method in ipairs(self.mPool) do
if method[1] then
--finds entities with required components
local matches = {}
for x=1, #self.ePool do
if band(self.ePool[x][1], method[2]) == method[2] then
matches[#matches+1] = x
end
end
--get components of entities
local components = {}
for x=1, #method[3] do
components[x] = {}
local marker=1
local savePosition = 1
for Eid=1, matches[#matches] do-- Eid = entity id
if Eid == matches[marker] then
components[marker][#components[marker]+1] = self.cPool[method[3][x]][savePosition]
marker = marker +1
end
if self.cBool[method[3][x]][Eid] then
savePosition = savePosition +1
end
end
end
--reorder and run as coroutine or function
if method[5] then
for x=1, #components do
coroutine.wrap(method[4])(matches[x], unpack(components[x]), dt)
end
else
for x=1, #components do
method[4](matches[x], unpack(components[x]), dt)
end
end
end
end
end
The problem is that if you set a variable to the value of table content the value not the reference will be set.
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!