Insert Additional data into Lua table at index - lua

I have a table called "inventory", initialized like so:
inventory = {}
inventory[1] = { qty = 0 }
I want to add more data to this table, at the index 1, eg:
val = { id = "example" }
inventory[1] = inventory[1], val
Is there a way I can do this while preserving the data that is already in this table at this index?
The final result should be something like:
inventory[1] = { qty = 0, id = "example" }
But if I try to print the id after trying this code I get:
print(inventory[1].id) == Nil

inventory[1].id = "example"
or
inventory[1]["id"] = "example"
or
this other SO answer with first_table being inventory[1] and second_table being val.
FWIW, you'd need 2 variables on the left side of the expression for inventory[1] = inventory[1], val to work: a, b = x, y.

You need to take the first key in the table and use it:
local inventory = {}
inventory[1] = { qty = 0 }
local val = { id = "example" }
--
local KeyName = next(val)
inventory[1][KeyName] = val[KeyName]
print(inventory[1][KeyName])
-- or
print(inventory[1].id)

Related

Spawning an Object with State TTS

I would like to combine two and more objects in the TabletopSimulator. Wenn I spawn the objects I can combine like this page https://kb.tabletopsimulator.com/host-guides/creating-states/. I would like this create with Lua. So I need help... I spawn the objects like here, but I didn`t get two objects with 2 states.
function SpawnLevel1(Obj1, ID)
CID = ID
spawnparamslvl = {
type = 'Custom_Assetbundle',
position = Obj1.getPosition(),
rotation = Obj1.getRotation(),
scale = {x=1, y=1, z=1},
}
paramslvl = {
assetbundle = data[CID].assetbundle,
type = 1,
material = 0,
}
Obj2 = spawnObject(spawnparamslvl)
obj_name = data[CID].display_name
Obj2.setDescription(obj_name)
Obj2.setName(obj_name)
Obj2.setCustomObject(paramslvl)
Obj1.addAttachment(Obj2).SetState(1)
end
function deploy(PID)
display_name = data[PID].display_name
spawnparams = {
type = 'Custom_Assetbundle',
position = self.getPosition(),
rotation = self.getRotation(),
scale = {x=1, y=1, z=1},
}
params = {
assetbundle = data[PID].assetbundle,
type = 0,
material = 0,
}
Spawning(spawnparams, params, display_name, PID)
end
function Spawning(spawnparams, params, display_name, PID)
Obj1 = spawnObject(spawnparamsmain)
ID = PID
Level1 = SpawnLevel1(Obj1, ID)
Obj1.setCustomObject(paramsmain)
Obj1.setName(display_name)
end
Thank you for your help
Radoan
You have to use spawnObjectData or spawnObjectJSON. The format of the "object data" follows the format of the save file.
Rather than hardcoding the large data structures needed to build an object, I'll use existing objects as templates. This is a common practice that's also reflected by the following common idiom for modifying an existing object:
local data = obj.getData()
-- Modify `data` here --
obj.destruct()
obj = spawnObjectData({ data = data })
The following are the relevant bits of "object data" for states:
{ -- Object data (current state)
-- ...
States = {
["1"] = { -- Object data (state 1)
--- ...
},
["3"] = { -- Object data (state 3)
-- ...
},
["4"] = { -- Object data (state 4)
-- ...
}
},
-- ...
}
So you could use this:
function combine_objects(base_obj, objs_to_add)
if not objs[1] then
return base_obj
end
local data = base_obj.getData()
if not data.States then
data.States = { }
end
local i = 1
while data.States[tostring(i)] do i = i + 1 end
i = i + 1 -- Skip current state.
while data.States[tostring(i)] do i = i + 1 end
for _, obj in ipairs(objs_to_add) do
data.States[tostring(i)] = obj.getData()
obj.destruct()
i = i + 1
end
base_obj.destruct()
return spawnObjectData({ data = data })
end

Update Elements in table without changing table order Lua

I'd like to maintain the order of a table when updating table values in Lua.
Example
tbl = {
messageId = 0,
timestamp = currentTime,
responseStatus = {
status = "FAILED",
errorCode = "599",
errorMessage = "problem"
}
}
meaning tbl.messageId = 12345 leaves the elements ordered
Like #moteus said, your premise is incorrect: non-numeric entries in Lua tables are not sorted. The order, in which they are defined won't, in general, be the same order as that in which they will be read (e.g., pairs will iterate over those entries in an arbitrary order). Assigning a new value will not affect this in any way.
I suppose you can use table.sort, there is a simple example:
local tbl = {
messageId = 0,
timestamp = currentTime,
responseStatus = {
status = "FAILED",
errorCode = "599",
errorMessage = "problem"
}
}
function fnCompare (e1, e2)
-- you should promise e1 and e2 is tbl struct
-- you can check e1 and e2 first by yourself
return e1.messageId < e2.messageId;
end
-- test
local tbAll = {}
tbl.messageId = 3;
table.insert(tbAll, tbl);
-- add a another
table.insert(tbAll, {messageId = 1});
table.sort(tbAll, fnCompare);
for k, v in ipairs(tbAll) do
print(v.messageId); -- result: 1 3
end

World of Warcraft Lua - sort table

I'm trying to sort a table for a addon/weakaura but I do not see how to do it ( sort by the attribut value).
Example :
player = {
value = 34
class = Warrior,
id = 1
},
{
value = 1,
class = mage,
id = 2
},
{
value = 3443,
class = Paladin,,
class = 3
}
I want :
player = {
value = 1,
class = mage,
id = 2
},
{
value = 34
class = Warrior,
id = 1
},
{
value = 3443,
class = Paladin,
class = 3
}
Someone an idea how to do this ?
Assuming you fix your table declaration, you can sort the table using a custom function:
local player = {
{ value = 34, class = "Warrior", id = 1 },
{ value = 1, class = "mage", id = 2 },
{ value = 3443, class = "Paladin", id = 3 },
}
table.sort(player, function(a,b) return a.value < b.value end)
This will sort elements of the player table by the value of the value field. You can come up with a more elaborate sorting condition if needed.
Refer to http://www.lua.org/manual/5.3/manual.html#pdf-table.sort for more information on table.sort

Split Lua string into tables with subtables

All the examples for splitting strings generate arrays. I want the following
Given string like x.y.z e.g. storage.clusters.us-la-1
How do I generate a table from that resembling
x = {
y = {
z = {
}
}
}
Below is a function that should do what you want.
function gen_table(str, existing)
local root = existing or {}
local tbl = root
for p in string.gmatch(str, "[^.]+") do
local new = tbl[p] or {}
tbl[p] = new
tbl = new
end
return root
end
Usage:
local t = gen_table("x.y.z")
local u = gen_table("x.y.w", t)
t.x.y.z.field = "test1"
t.x.y.w.field = "test2"

Sort table with gaps

I got a table which is not meant to be sorted in a way I need it to be sorted at a specific point.
Thus, I cannot sort the table while creation but have to sort it when needed.
Problem is, there are plenty gabs in the indeces and the Values I want to sort here are nested.
Simplified model:
table = {
[1] = { a = 1 , b = 31231, c = { c1 = "foo" , true } },
[8] = { a = 2 , b = 5231 , c = { c1 = "bar" , true } },
[92] = { a = 8 , b = 2 , c = { c1 ="asdgköbana" , false } },
}
Now I want to sort this table by length of c[1].
How can I do that in the fastest way? Length of table in first dimension will stay under 100 entries.
Indices don't need to be kept. So by a table with 3 entries, it's okay when last index is [3] after the portage. Basicly in this case, I only use the index to identifies neighbors, they have no prior use.
Using table as a variable kills the table library, which you need to get the sort function.
Try the code below. Note that it makes a new table to hold the sorted list but reuses the internal tables.
local t = {
[1] = { a = 1 , b = 31231, c = { c1 = "foo" , true } },
[8] = { a = 2 , b = 5231 , c = { c1 = "bar" , true } },
[92] = { a = 8 , b = 2 , c = { c1 ="asdgköbana" , false } },
}
local s = {}
for k,v in pairs(t) do
s[#s+1]=v
end
table.sort(s,function (a,b)
return #a.c.c1 < #b.c.c1
end)
for k,v in ipairs(s) do
print(k,v.a,v.c.c1)
end

Resources