Lua: Saving and opening a two dimensional table indexed by key - lua

Apologizes if the semantics is erroneous in my question, but the code below should explain what my goal is.
I've created a table like so:
local a1 = {}
a1.hammer = {
price = 10,
quantity = 5,
category = "tools",
}
a1.saw = {
price = 15,
quantity = 4,
category = "tools",
}
a1.screwdriver = {
price = 4,
quantity = 12,
category = "tools",
}
Printing the contents of this table gives:
{hammer = {price = 10,
quantity = 5,
category = "tools"},
saw = {price = 15,
quantity = 4,
category = "tools"},
screwdriver = {price = 4,
quantity = 12,
category = "tools"}}
Question 1: How do I access the price of the screwdriver (ie. field of a table of a table)
Question 2:
How do I:
Save table a1 to a file
Open the file and import the table the next time I run the application
Note: local a2 = a1 returns nil for a2 rather than assigning the reference of a1 to a2. There's an issue here...

#Luke Allison
I may have an answer to your first question:
Question 1: How do I access the price of the screwdriver (ie. field of
a table of a table)
you can try this code:
print( a1["screwdriver"]["price"] )
Result = 4.
As for the second question you should have a look at the link in the comments above.
Hope that helps.

Related

How to get x first objects from table - lua

I'm pretty new in lua and I have a problem that I've been trying to solve for several hours now.
So simply I have one table with 4 other tables (sry idk how it's named).
local myTable = {
player1 = {id = 1, points = 100},
player2 = {id = 3, points = 200},
player3 = {id = 4, points = 150},
player4 = {id = 7, points = 150}}
Id and points are random numbers.
All I want to do is get only 2 first tables from that table and use their values.
player1 = {id = 1, points = 100}
player2 = {id = 3, points = 200}
I would really appreciate your help, it's very tiring.
All I want to do is get only 2 first tables from that table and use
their values.
To get the inner tables just index myTable with the keys you've stored to inner tables at.
local table1 = myTable.player1
local table2 = myTable.player2
print("Player 1 has " .. table1.points .. " points")
How to get x first objects from table - lua
To answer this you would need to have a table with an order. Lua doesn't know the order of your table unless you have numerical keys.
If your table was like
local players = {
{id = 1, points = 100},
{id = 3, points = 200},
{id = 4, points = 150},
{id = 7, points = 150}}
You would simply pick players[1] and so forth to get the first x elements.
In your case you could do something like
myTable["player"..i] for i from 1 to x assuming that the keys represent the table order.
First you need is sort your table:
local myTable = {
{id = 1, points = 100},
{id = 3, points = 200},
{id = 4, points = 150},
{id = 7, points = 150}
}
You don't need to index those values as 'player1', 'player2', etc. So if you want the index(es) to appear as player1, etc. return the index and concatenated as player, like:
for key, value in pairs(myTable) do
print('player' .. key)
end
The past code will print all table indexes with prefix 'player'.
But to get only the first two values; what we can do? Simple! Make a function:
local myTable = {
{id = 1, points = 100},
{id = 3, points = 200},
{id = 4, points = 150},
{id = 7, points = 150}
}
local function collect(table, howMuch)
local response, index = {}, 1
for key, value in pairs(table) do
response[key] = howMuch and index <= howMuch and value or nil
index = index + 1
end
return response
end
local response = collect(myTable, 2)
print(response[1].id, response[2].id, response[3]) -- 1, 3, nil
What this function do?
Collect values from the first argument named table, and in base the second argument named howMuch (as a max of the response) return those values.
Or for friends: iters table myTable and only returning a table containing 2 fields.

Lua table.insert - strange behaviour when inserting to table

I'm having a bit of a hard time figuring out why my code is behaving the way it is. I have a table named players, structured as key, value pairs. The values are also nested tables (items). Each item, should contain at least one unique identifier, named 'id', contained withing the nested table (key name) 'specs'.
players = {
['identifier_one'] = {
{
["label"] = "Flashlight",
["weight"] = 1,
["name"] = "WEAPON_FLASHLIGHT",
["specs"] = {
["pockets"] = false,
["id"] = "ZT345", --This is our unique identifier
["equip"] = true,
["stack"] = 1,
["craft"] = true
}
},
{
["label"] = "Flashlight",
["weight"] = 1,
["name"] = "WEAPON_FLASHLIGHT",
["specs"] = {
["pockets"] = false,
["id"] = "ACF124",
["equip"] = true,
["stack"] = 1,
["craft"] = true
}
}
},
['another_item'] = {
...
},
}
I've got the data structure writing correctly. However, when I insert a new nested item, it's adding the newItem to the next increment within the table as expected, and at the same time it's overwriting all of the previus indexes. So the previous items ['spec']['id'] becomes the newItem id if that makes sense? So looking at the above layout, the previous id 'ZT345' would become 'ACF124'. Thus making the two items identical.
When I print out what the newItem consists off, everything is perfect and should write to the table as intended. At first, I thought it may have been something related to the encoding the table into json when writing to the database. However, if I print out the players[identifier] table, after inserting the newItem, it has then overwritten all previous indexes. So I'm pretty certain the issue is upon inserting the newItem to my players[identifier]
My code is as follows:
ESX.RegisterServerCallback('zombie-inventory:itemCheck', function(source, cb, item)
--check our item is allowed to be added.
if items[item] then
local src = source
local identifier = getIdentifier(src)
local newItem = items[item]
if string.match(item, 'WEAPON') then
newItem['specs'][1].id = genId(players[identifier])
end
--This point is where the code falls apart.
table.insert(players[identifier], newItem)
MySQL.Async.execute('UPDATE `user_inventory` SET `inventory` = #inventory WHERE `identifier` = #identifier', {
['#identifier'] = identifier,
['#inventory'] = json.encode(players[identifier])
})
cb(true)
else
print(('[inventory] [^3WARNING^7] invalid item for itemCheck cb: %s'):format(item))
end
end)
Just to add, the genId() function is 100% returning a unique id, I've printed the id numerous times, and it's always different.

Best way to saving completed progress in table?

So, i have empty table.
local data_tbl = {}
But i need save data when user complete current task.
Like:
-- (1, 2, 21) it's task id.
data_tbl['1'] = true
data_tbl['2'] = true
data_tbl['21'] = true
And in table "data_tbl" it's look like
data_tbl {
1 = true,
2 = true,
21 = true,
}
I wan't saving only completed task. Not all , because it's very heavy ?
But when i wanted remove this key , like 21 , i'ts get nothing effect.
table.remove(data_tbl, 21)
Task with 21 index not removed. Why ?
Maybe have other best way for all this ? (Saving complete tasks)
I don't want use table.Add() because it's added to last position. Like table.Add(data_tbl, {completed_id = 21})
And in table it's look like.
data_tbl {
1 = {completed_id = 21}
}
-- It's get me more table checks... and cycles , i don't want.
table.insert and table.remove are meant for sequences, but you're using the table as a map. If you have a key, say 21 and want to unset it, just do data_tbl[21] = nil
lua tables are hash tables, to insert data to table use mytable[name] = value or mytable.myname = value, to remove from table mytable[name] = nil or mytable.myname = nil.
To simulate arrays lua tables has helper functions in module table and some sort of optimizations, but id's must be numbers and begin with 1.
For mixed tables like mytable[1] = true; mytable[2] = true; mytable[3] = true; mytable[21] = true; mytable.name = 'values', #mytable evaluates to length of 3 as entries [21] and 'name' do not form the sequence.
table.remove and table.insert modifies 'array' shifting corresponding elements:
local mytable = {1, 2, 3, 4}
table.remove(mytable, 2)
print(table.concat(mytable, ',')) -- result is {1, 3, 4 }
table.insert(mytable, 2, 5)
print(table.concat(mytable, ',')) -- result is {1, 5, 3, 4 }
Numeric strings as keys will be not converted internally into numbers (like in javascript) and will not work with array like methods:
local mytable = {}
mytable[21] = 'value21'
mytable['21'] = 'string21'
-- table content: {[21] = 'value21', ['21'] = 'string21'}

PowerQuery multiple files and add column

I have the inline PowerQuery to automate my weekly reporting. Since I am new to power query I followed up this tutorial and try to add a custom column so I can use it to see week over week improvements, the thing is that the column that is added is not named "Week" but instead it is called the name of the file. From this webpage the second parameter is column name. I do not find why column name is filename instead of the name "week".
let ExcelFile = (FilePath, FileName) =>
let
Source = Folder.Files(FilePath),
File = Source{[#"Folder Path"=FilePath,Name=FileName]}[Content],
ImportedExcel = Excel.Workbook(File),
Sheet1 = ImportedExcel{[Name="Page1_1"]}[Data],
TableWithWeek = Table.AddColumn(Sheet1,"Week", each FileName),
TableWithoutHeader = Table.Skip(TableWithWeek,3),
FirstRowAsHeader = Table.PromoteHeaders(TableWithoutHeader)
in
FirstRowAsHeader
in
ExcelFile
This call:
FirstRowAsHeader = Table.PromoteHeaders(TableWithoutHeader)
will replace the column names you have with the values from the first row. Since the first value under the column "Week" is the filename, then your table will now use that filename as the column name.
You can fix this by adding the custom column after you use PromoteHeaders:
let ExcelFile = (FilePath, FileName) =>
let
Source = Folder.Files(FilePath),
File = Source{[#"Folder Path"=FilePath,Name=FileName]}[Content],
ImportedExcel = Excel.Workbook(File),
Sheet1 = ImportedExcel{[Name="Page1_1"]}[Data],
TableWithoutHeader = Table.Skip(Sheet1, 3),
FirstRowAsHeader = Table.PromoteHeaders(TableWithoutHeader),
TableWithWeek = Table.AddColumn(FirstRowAsHeader,"Week", each FileName),
in
TableWithWeek
in
ExcelFile

Give one variable a number value and string value?

I am trying to have one variable that has a number value as well as a string value.
I am coding in Lua and I don't know how to do this. Is it possible?
Tables. They are like a filing cabinet where you can store as many values as you want and retrieve them given some kind of "key". In Lua, the key can be any type, but the most common key is going to be a numerical index or a string.
Given:
local age = 30 -- your number values
local name = 'Fred' -- your string value
There's a tons of different ways we can structure that in Lua:
local person = { age = 30, name = 'Fred' )
print(person.age, person.name)
local person = { 'Fred', 30 }
print(person[1], person[2])
print(unpack(person))
local person = { Fred = 30 }
print(person.Fred)
local person = { [30] = 'Fred' }
print(person[30])
So on and so forth.
So if i use..
coal = { name = "Coal", value = 80 }
I can then do this?
userInput = read()
if userInput == coal.name then
fuelUse = coal.value
end

Resources