Merge Tables with Remainders - Lua - lua

What I have is a nested table (two-levels). What I'm looking to do is merge (flatten?) the sub-tables, with any duplicates spilling over into new keys.
So the input would look like
t = {
[1] = {
[1] = "One",
[3] = "Three"
},
[2] = {
[2] = "Two",
[3] = "Three"
},
[3] = {
[1] = "One",
[2] = "Two",
[4] = "Four"
}
}
and the output would look like
t = {
[1] = {
[1] = "One",
[2] = "Two",
[3] = "Three",
[4] = "Four"
}
[2] = {
[1] = "One",
[2] = "Two",
[3] = "Three"
}
}
The input table would be up to 1000 keys, so I'm hoping it can be done efficiently.

local bottom, max_btm = {}, 0
for top = #t, 1, -1 do
for k, v in pairs(t[top]) do
local btm = bottom[k] or 0
if btm < top then
repeat btm = btm + 1
until btm == top or not t[btm][k]
if btm ~= top then
t[btm][k], t[top][k] = v
end
bottom[k] = btm
max_btm = math.max(max_btm, btm)
end
end
if max_btm < top then
t[top] = nil
end
end

Try this:
local d={}
for k,v in pairs(t) do
if k~=1 then
for kk,vv in pairs(v) do
if t[1][kk]==nil then
t[1][kk]=vv
else
d[kk]=vv
end
end
t[k]=nil
end
end
t[2]=d

Related

Changing value in table in Lua

I am trying to make a table and want to change a value in that table for a particular key. The thing is when I do change the key it does change for all the keys.
function dump(o, nb)
if nb == nil then
nb = 0
end
if type(o) == 'table' then
local s = ''
for i = 1, nb + 1, 1 do
s = s .. " "
end
s = '{\n'
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
for i = 1, nb, 1 do
s = s .. " "
end
s = s .. '['..k..'] = ' .. dump(v, nb + 1) .. ',\n'
end
for i = 1, nb, 1 do
s = s .. " "
end
return s .. '}'
else
return tostring(o)
end
end
Config={}
PlayersStatusTable={}
Config.DefaultStatus = {
hunger = 1000000,
thirst = 1000000,
}
local timeNow = os.clock()
PlayersStatusTable[12] = Config.DefaultStatus
PlayersStatusTable[112] = Config.DefaultStatus
PlayersStatusTable[54] = Config.DefaultStatus
for playerId, details in pairs(PlayersStatusTable) do
print("playerid1",playerId)
print(dump(PlayersStatusTable))
print(dump(PlayersStatusTable[112]))
print(dump(PlayersStatusTable[112].hunger))
PlayersStatusTable[112].hunger = 5
end
the output is this:
playerid1 112
{
[112] = {
["thirst"] = 1000000,
["hunger"] = 1000000,
},
[54] = {
["thirst"] = 1000000,
["hunger"] = 1000000,
},
[12] = {
["thirst"] = 1000000,
["hunger"] = 1000000,
},
}
{
["thirst"] = 1000000,
["hunger"] = 1000000,
}
1000000
playerid1 54
{
[112] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
[54] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
[12] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
}
{
["thirst"] = 1000000,
["hunger"] = 5,
}
5
playerid1 12
{
[112] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
[54] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
[12] = {
["thirst"] = 1000000,
["hunger"] = 5,
},
}
{
["thirst"] = 1000000,
["hunger"] = 5,
}
5
I just want the hunger of id 112 to be 5.
You're assigning the same table to all 3 keys, so they all point to the same table that's being changed. You need to ensure that you're creating a new table when you assign to each key.
local function shallowCopy(t)
local result = {}
for k, v in pairs(t) do
result[k] = v
end
return result
end
PlayersStatusTable[12] = shallowCopy(Config.DefaultStatus)

How to print a table's contents within a table? [Lua]

What I want to do is ONLY print a table's contents within a table. For example:
local stats = {
table1 = {
tTable1 =
{
data = 1
},
tTable2 =
{
data2 = 2
},
tTable3 =
{
data3 = 3
},
}
}
I don't really care about table1 or all the tTables but rather the information in the data variables. How can I print them?
This is a snippet of my real code:
local stats = {
[1] = {
[1] = {
[1] = 1,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cooler,
[2] = 10,
["n"] = 2,
},
["n"] = 2,
},
[2] = {
[1] = {
[1] = 2,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cell_block,
[2] = 0,
["n"] = 2,
},
["n"] = 2,
},
[3] = {
[1] = {
[1] = 3,
[2] = -1,
[3] = -1,
["n"] = 3,
},
[2] = {
[1] = nuclearcraft:cooler,
[2] = 10,
["n"] = 2,
},
["n"] = 2,
},
}
This code actually goes on for a bit longer than this. In the real code, I don't care for any of the data except for the areas where it says "nuclearcraft" and the number beneath it.
recursive table traversal is suitable for this case:
local function TablePrint(t)
for k,v in pairs(t) do
if type(v)=="table" then
print(k)
TablePrint(v)
else
print('\t',k,v)
end
end
end
TablePrint(stats)
result:
table1
tTable3
data3 3
tTable2
data2 2
tTable1
data 1
keep in mind that the order of non-index values in the table is not defined

Remove specific entry from Lua table

I am inserting into a table like this
Admin = {}
table.insert(Admins, {id = playerId, Count = 0})
And that works fine.
How do I remove that specific admin from that table now?
The following does not work, and Im sure its because ID is stored in an array that's inside of the table, but how would I access that then?
table.remove(Admins, playerId)
Basically,
I want to remove from the table Admins, where the ID == playerId that I input.
There are two approaches to remove an entry from the table, both are acceptable ways:
1. myTable[index] = nil Removes an entry from given index, but adds a hole in the table by maintaining the indices
local Admins = {}
table.insert(Admins, {id = 10, Count = 0})
table.insert(Admins, {id = 20, Count = 1})
table.insert(Admins, {id = 30, Count = 2})
table.insert(Admins, {id = 40, Count = 3})
local function removebyKey(tab, val)
for i, v in ipairs (tab) do
if (v.id == val) then
tab[i] = nil
end
end
end
-- Before
-- [1] = {['Count'] = 0, ['id'] = 10},
-- [2] = {['Count'] = 1, ['id'] = 20},
-- [3] = {['Count'] = 2, ['id'] = 30},
-- [4] = {['Count'] = 3, ['id'] = 40}}
removebyKey(Admins, 20)
-- After
-- [1] = {['Count'] = 0, ['id'] = 10},
-- [3] = {['Count'] = 2, ['id'] = 30},
-- [4] = {['Count'] = 3, ['id'] = 40}
2. table.remove(myTable, index)
Removes the entry from given index and renumbering the indices
local function getIndex(tab, val)
local index = nil
for i, v in ipairs (tab) do
if (v.id == val) then
index = i
end
end
return index
end
local idx = getIndex(Admins, 20) -- id = 20 found at idx = 2
if idx == nil then
print("Key does not exist")
else
table.remove(Admins, idx) -- remove Table[2] and shift remaining entries
end
-- Before is same as above
-- After entry is removed. Table indices are changed
-- [1] = {['id'] = 10, ['Count'] = 0},
-- [2] = {['id'] = 30, ['Count'] = 2},
-- [3] = {['id'] = 40, ['Count'] = 3}

Most optimized way to get value from table

I need to check if first value is >= 'from' and second value is <= 'to', if true then my function retun number. It's working but I don't know if this is the best and most optimized way to get value(number from table).
local table = {
{from = -1, to = 12483, number = 0},
{from = 12484, to = 31211, number = 1},
{from = 31212, to = 53057, number = 2},
{from = 53058, to = 90200, number = 3},
{from = 90201, to = 153341, number = 4},
{from = 153342, to = 443162, number = 5},
{from = 443163, to = 753380, number = 6},
{from = 753381, to = 1280747, number = 7},
{from = 1280748, to = 2689570, number = 8},
{from = 2689571, to = 6723927, number = 9},
{from = 6723928, to = 6723928, number = 10}
}
local exampleFromValue = 31244
local exampleToValue = 42057
local function getNumber()
local number = 0
for k, v in pairs(table) do
if (v.from and exampleFromValue >= v.from) and (v.to and exampleToValue <= v.to) then
number = v.number
break
end
end
return number
end
print(getNumber())
With this small amount of data, such function doesn't seem like a performace issue. However, you can compress the data a bit:
local t = {
12484, 31212, 53058, 90201, 153342, 443163, 753381, 1280748, 2689571, 6723928
}
local exampleFromValue = 31244
local exampleToValue = 42057
local function getNumber()
local last = -1
for i, v in ipairs(t) do
if exampleFromValue >= last and exampleToValue < v then
return i - 1
end
last = v
end
return 0
end

how to understand a table of tables in lua?

> polyline = {color = "blue", thickness = 2, npoints = 4, {x=0,y=0}, {x=-10,y=0}, {x=-10,y=1}, {x=0,y=1}}
> print(polyline[2])
table: 0x55ad5c0f3f90
> print(polyline[2].x)
-10
Why does print(polyline[2]) give out -10 ?
If you do not provide a key explicitly, table elements are assigned to numeric keys within the table constructor.
polyline = {color = "blue", thickness = 2, npoints = 4, {x=0,y=0}, {x=-10,y=0}, {x=-10,y=1}, {x=0,y=1}}
is equivalent to
do
polyline = {}
polyline.color = "blue"
polyline.thickness = 2
polyline.npoints = 4
do
polyline[1] = {}
polyline[1].x = 0
polyline[1].y = 0
end
do
polyline[2] = {}
polyline[2].x = -10
polyline[2].y = 0
end
do
polyline[3] = {}
polyline[3].x = -10
polyline[3].y = 1
end
do
polyline[4] = {}
polyline[4].x = 0
polyline[4].y = 1
end
end
Refer to
https://www.lua.org/manual/5.3/manual.html#3.4.9

Resources