table.insert adding a unknown table - lua

So im trying to add a table inside another table but each time i do it, it adds a "1": from nowhere...
my code :
local previousClothes = json.decode(xPlayer.get('clothes'))
print("old previousClothes"..json.encode(previousClothes))
local clothes = {[label] = {[parentName] = parentValue, [partName] = partValue}}
print("old clothes"..json.encode(clothes))
clothes[#clothes+1] = previousClothes
print("new clothes: "..json.encode(clothes))
xPlayer.get('clothes') = my clothes stored in my db
local clothes = my new clothes received in the function/event
and here comes my issue.. it adds a "1": to my table
https://i.stack.imgur.com/sb5pj.png

Instead of adding previousClothes as an array element to clothes, you can copy key-value pairs of previousClothes into clothes.
for k, v in pairs(previousClothes) do
clothes[k] = v
end
I assume this is what you want.

Because Your clothes is not an array, see the documentation in here. When you use # get a table length, it is better to be an array.

Related

(Godot) Saving multiple keys and reloading them

I'm kind of stumped. I've followed and adapted the save system from this.
To phrase the problem, I'm unsure how to load the dictionaries back into the original variables.
Most likely easier to explain the problem as you see it.
# This would be "GlobalData"
onready var KEY = name
# Stats dictionary
var stats:= {
"health" : 75,
"stamina": 25
}
# Meta Dictionary
var meta:= {
"testing": "I'm a totally random thing",
"testing2": 2002,
"date": "Thursday, 2020-08-20, 20:12"
}
# Load both into array to iterate through upon saving
var list = [stats, meta]
func save(save_game:Resource):
var i = 0
for element in list:
# Make a unique key based on iteration
var temp:String = KEY + String(i)
# Store data to key
save_game.data[temp] = element
i = i+1
func load(save_game:Resource):
var i = 0
# === Where the error lies === #
# While saving works fine, I cannot use the list array to push content back into the original dictionaries
# If I targeted the dictionary by it's variable, then it got applied.
for element in list:
var temp:String = KEY + String(i)
element = save_game.data[temp]
i = i+1
So, my question relies in "how do I re-apply the loaded data?".
Do I have to write the list into a way, that it would store the dictionary name too? Or is it possible to somehow call the name of the element to get it to target the original variable/dictionary?
PS. Don't ask why I'm not using i++ or i+=1. Errors out.
The KEY value, as used by GDQuest in that video, identifies the node on which the save/load methods are called, not every piece of data you save individually.
You have many options to achieve what you want. This are two simple ones:
1 - More in line with what the video is doing: create a dictionary to contain all your separate information, and store that under the node unique key.
...
func save(save_game:Resource):
var node_data = {
stats = stats,
meta = meta,
}
save_game.data[KEY] = node_data
func load(save_game:Resource):
stats = save_game.data[KEY].stats
meta = save_game.data[KEY].meta
2 - More in line with what you are trying to do: create unique fixed keys for each dictionary/element you are storing, and use that to save/load them.
onready var KEY_STATS = name + "_stats"
onready var KEY_META = name + "_meta"
...
func save(save_game:Resource):
save_game.data[KEY_STATS] = stats
save_game.data[KEY_META] = meta
func load(save_game:Resource):
meta = save_game.data[KEY_STATS]
stats = save_game.data[KEY_META]
Haven't tried any of this, but it should be at least a reference of where your problem is.
Please, for future questions, include all the relevant code, or at least provide a link to the source if it's too big to include in the question. https://stackoverflow.com/help/how-to-ask

How can i keep this table in the shown order?

Hello i have got a table, that uses string indexes:
shirt = {
["shirtwhite.png"] = "shirt_white.png",
["shirtwhite.png^[multiply:#3f3f3f"] = "shirt_white.png^[multiply:#3f3f3f",
["shirtwhite.png^[multiply:#ff0000"] = "shirt_white.png^[multiply:#ff0000",
["shirtwhite.png^[multiply:#ff7f00"] = "shirt_white.png^[multiply:#ff7f00",
["shirtwhite.png^[multiply:#ffff00"] = "shirt_white.png^[multiply:#ffff00",
["shirtwhite.png^[multiply:#00ff00"] = "shirt_white.png^[multiply:#00ff00",
["shirtwhite.png^[multiply:#0000ff"] = "shirt_white.png^[multiply:#0000ff",
["shirtwhite.png^[multiply:#9f00ff"] = "shirt_white.png^[multiply:#9f00ff",
},
Theese are t-shirt-textures for an editable game-character-skin (with colour-values for different colors).
There are some more of theese tables in the code, for other parts of the character-skin
how can I keep the table in it´s shown order, while it´s loaded in this code-snippet?
The tzables are in a file "skins.lua" and the code-snippet is from another lua-file
character_creator = {}
character_creator.skins = dofile(minetest.get_modpath("character_creator") .. "/skins.lua")
local skins = character_creator.skins
local skins_array = {}
minetest.after(0, function()
local function associative_to_array(associative)
local array = {}
for key in pairs(associative) do
table.insert(array, key)
end
return array
end
skins_array = {
skin = associative_to_array(skins.skin),
hair = associative_to_array(skins.hair),
eyes = associative_to_array(skins.eyes),
shirt = associative_to_array(skins.shirt),
pants = associative_to_array(skins.pants),
}
end)
In Lua only arrays (positive integer-indexed tables) have "order" (can be iterated using ipairs); the hash tables (like the one you are working with) are unordered. If you want to iterate over a table like this in a specific order, you'd usually create an array with the keys, sorted them in the order you want and then iterate over that array extracting elements from your table.
There are also components (like ordered table) that may keep track of insertions and return results in the same order, if that's what you want.

Lua how to access specific data in a nested table

I parsed some data from a CSV file to a Lua table.
Lets say the table looks like this just bigger
tab {
{ id = 1761, anotherID=2, ping=pong}
{ id = 2071, anotherID=4, ping=notpong}
}
Now I want to know every ID (without displaying any other data yet) to store them in another table for some time.
I am completely lost here for now..
Using what you wrote I rewrote it a bit and went to have:
minitab = {}
for i, value in ipairs(tab) do
local id = value.id
local anotherID = value.anotherID
minitab[id] = anotherID
end
Would that work? In fact i later want to get just 2 values of a way larger array (around 30 datas) - but I can only push a single array to a GUI dropdown. I want to save the ID as a key and the "anotherID" value wich will be a text after that key so if a ask for the 2071st value it displays the "name" 4
The code below stores the ids as keys in another table:
id={}
for k,v in ipairs(tab) do
id[v.id]=true
end
You can then traverse id with pairs to list the ids.
If you want to remember where each id came from, use id[v.id]=k in the loop.
Based on your question, you can use this code to traverse your data table tab and get minitab to be used for your GUI array:
--data
tab = {
{id = "4204", label = "2", desc = "Roancyme"},
{id = "5517", label = "9", desc = "Bicktuft"},
{id = "1035", label = "3", desc = "Pipyalum"},
}
--temporary table
local minitab = {}
for i, option in ipairs(tab) do
minitab[option.id] = option.label
end
--print minitab
print('<select>')
for id, label in pairs(minitab) do
print(string.format('<option value="%s">%s</option>', id, label)) --> <option value="1035">3</option>
end
print('</select>')
print()
However, I don't think it is necessary to create a temporary table to store those values, because you can easily traverse your original table tab and directly pull out the output you need; like this:
--print directly from tab
print('<select>')
for i, option in ipairs(tab) do
print(string.format('<option value="%s">%s</option>', option.id, option.label)) --> <option value="1035">3</option>
end
print('</select>')
print()
Unless you need to work with it before displaying the list on the drop down (e.g. add some prefix to the label, sort minitab by the label, etc); but you don't want to disturb the original data table tab. In this case, it would make sense to use the temporary table.
--format values in temporary table
local minitab = {}
for i, option in ipairs(tab) do
local minitabID = option.id
local minitabLabel = string.format('Item %s - %s', option.label, option.desc)
table.insert(minitab, {id = minitabID, label = minitabLabel})
end
--sort temporary table
table.sort(minitab, function (o1, o2) return o2.label > o1. label end)
--print formatted values from temporary table
print('<select>')
for i, option in ipairs(minitab) do
print(string.format('<option value="%s">%s</option>', option.id, option.label)) --> <option value="4204">Item 2 - Roancyme</option>
end
print('</select>')
NB: Please take a note on which table iteration uses ipairs and which one uses pairs. See the complete code snippet here.

lua: user input to reference table

I am having trouble with my tables, I am making a text adventure in lua
local locxy = {}
locxy[1] = {}
locxy[1][1] = {}
locxy[1][1]["locdesc"] = "dungeon cell"
locxy[1][1]["items"] = {"nothing"}
locxy[1][1]["monsters"] = {monster1}
The [1][1] refers to x,y coordinates and using a move command I can successfully move into different rooms and receive the description of said room.
Items and monsters are nested tables since multiple items can be held there (each with their own properties).
The problem I am having is getting the items/monsters part to work. I have a separate table such as:
local monsters = {}
monsters["rat"] = {}
monsters["rat"]["Name"] = "a rat"
monsters["rat"]["Health"] = 5
monsters["rat"]["Attack"] = 1
I am using a table like this to create outlines for various enemy types. The monster1 is a variable I can insert into the location table to call upon one of these outlines, however I don't know how to reference it.
print("You are in ", locxy[x][y]["locdesc"]) -- this works
print("You can see a ", locxy[x][y]["monsters]["Name"],".") - does not work
So I would like to know how I can get that to work, I may need a different approach which is fine since I am learning. But I would also specifically like to know how to / if it possible to use a variable within a table entry that points to data in a separate table.
Thanks for any help that can be offered!
This line
locxy[x][y]["monsters]["Name"]
says
look in the locxy table for the x field
then look in the y field of that value
look in the "monsters"` field of that value
then look in the "Name" field of that value
The problem is that the table you get back from locxy[x][y]["monsters"] doesn't have a "Name" field. It has some number of entries in numerical indices.
locxy[x][y]["monsters][1]["Name"] will get you the name of the first monster in that table but you will need to loop over the monsters table to get all of them.
Style notes:
Instead of:
tab = {}
tab[1] = {}
tab[1][1] = {}
you can just use:
tab = {
[1] = {
{}
}
}
and instead of:
monsters = {}
monsters["rat"] = {}
monsters["rat"]["Name"] = "foo"
you can just use:
monsters = {
rat = {
Name = "foo"
}
}
Or ["rat"] and ["Name"] if you want to be explicit in your keys.
Similarly instead of monsters["rat"]["Name"] you can use monsters.rat.Name.

How to quickly initialise an associative table in Lua?

In Lua, you can create a table the following way :
local t = { 1, 2, 3, 4, 5 }
However, I want to create an associative table, I have to do it the following way :
local t = {}
t['foo'] = 1
t['bar'] = 2
The following gives an error :
local t = { 'foo' = 1, 'bar' = 2 }
Is there a way to do it similarly to my first code snippet ?
The correct way to write this is either
local t = { foo = 1, bar = 2}
Or, if the keys in your table are not legal identifiers:
local t = { ["one key"] = 1, ["another key"] = 2}
i belive it works a bit better and understandable if you look at it like this
local tablename = {["key"]="value",
["key1"]="value",
...}
finding a result with : tablename.key=value
Tables as dictionaries
Tables can also be used to store information which is not indexed
numerically, or sequentially, as with arrays. These storage types are
sometimes called dictionaries, associative arrays, hashes, or mapping
types. We'll use the term dictionary where an element pair has a key
and a value. The key is used to set and retrieve a value associated
with it. Note that just like arrays we can use the table[key] = value
format to insert elements into the table. A key need not be a number,
it can be a string, or for that matter, nearly any other Lua object
(except for nil or 0/0). Let's construct a table with some key-value
pairs in it:
> t = { apple="green", orange="orange", banana="yellow" }
> for k,v in pairs(t) do print(k,v) end
apple green
orange orange
banana yellow
from : http://lua-users.org/wiki/TablesTutorial
To initialize associative array which has string keys matched by string values, you should use
local petFamilies = {["Bat"]="Cunning",["Bear"]="Tenacity"};
but not
local petFamilies = {["Bat"]=["Cunning"],["Bear"]=["Tenacity"]};

Resources