How to run table and print a specific key - lua

I have a table:
employee = {
name = "John", age = 30,
name = "George", age = 35
}
Now, I want to run the whole table, and if the name "George" is found, then the appropriate age to be printed. How can I do this? From what I searched I found that you can run a list with the code for k, v in pairs(employee) do but I don't know how to continue from there.

Your table will need to be restructured to start off with.
employee = {
{name = "John", age = 30},
{name = "George", age = 35},
}
This will allow the age to always match up with the name. Then you could run:
for _,v in ipairs(employee) do
if v.name == "George" then
return v.age
end
end
You can even create it as a function so you can check whatever name you want:
function find_age(n)
for _,v in ipairs(employee) do
if v.name == n then
return v.age
end
end
end
Of course, this will return the age of every n in the table, though.
Updated for comment
You can do it with a function as well.
function add_employee(n,a)
table.insert(employee, {name = n, age = a})
end

Related

function only returning one value instead of both in lua

function GetCharacterName(source)
local xPlayer = QBCore.Functions.GetPlayer(source)
local name = xPlayer.PlayerData.charinfo.lastname
local name2 = xPlayer.PlayerData.charinfo.firstname
if xPlayer then
return name, name2
end
end
I'm trying to return the values of name and name2, however the return is only giving the first value. I'm newer to lua, and code in general, so just trying to learn
Additional places in which this function is called:
AddEventHandler("mdt:attachToCall", function(index)
local usource = source
local charname = GetCharacterName(usource)
local xPlayers = QBCore.Functions.GetPlayers()
for i= 1, #xPlayers do
local source = xPlayers[i]
local xPlayer = QBCore.Functions.GetPlayer(source)
if xPlayer.PlayerData.job.name == 'police' then
TriggerClientEvent("mdt:newCallAttach", source, index, charname)
end
end
TriggerClientEvent("mdt:sendNotification", usource, "You have attached to this call.")
end)
RegisterServerEvent("mdt:performVehicleSearchInFront")
AddEventHandler("mdt:performVehicleSearchInFront", function(query)
local usource = source
local xPlayer = QBCore.Functions.GetPlayer(usource)
if xPlayer.job.name == 'police' then
exports['ghmattimysql']:execute("SELECT * FROM (SELECT * FROM `mdt_reports` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(reports)
for r = 1, #reports do
reports[r].charges = json.decode(reports[r].charges)
end
exports['ghmattimysql']:execute("SELECT * FROM (SELECT * FROM `mdt_warrants` ORDER BY `id` DESC LIMIT 3) sub ORDER BY `id` DESC", {}, function(warrants)
for w = 1, #warrants do
warrants[w].charges = json.decode(warrants[w].charges)
end
exports['ghmattimysql']:execute("SELECT * FROM `player_vehicles` WHERE `plate` = #query", {
['#query'] = query
}, function(result)
local officer = GetCharacterName(usource)
TriggerClientEvent('mdt:toggleVisibilty', usource, reports, warrants, officer, xPlayer.job.name)
TriggerClientEvent("mdt:returnVehicleSearchInFront", usource, result, query)
end)
end)
end)
end
end)
There are two possible reasons.
name2 is nil
you're using the function call in a way that adjusts the number of return values to 1. This happens GetCharacterName(source) is not the last in a list of expressions or if you put that function call into parenthesis or you assign it to a single variable.
Edit:
Now that you've added examples of how you use that function:
local charname = GetCharacterName(usource)
In this case the result list of GetCharacterName is ajdusted to 1 value (name) as you only assingn to a single variable. If you want both return values you need two variables.
Either do it like so:
local lastName, firstName = GetCharactername(usource)
local charName = lastName .. ", " .. firstname
Then charName is "Trump, Donald" for example.
Or you return that name as a single string:
function GetCharacterName(source)
local xPlayer = QBCore.Functions.GetPlayer(source)
local name = xPlayer.PlayerData.charinfo.lastname
local name2 = xPlayer.PlayerData.charinfo.firstname
if xPlayer then
return name .. ", " .. name2
end
end
Then local charname = GetCharacterName(usource) will work
local name1, name2 = GetCharactersName()

Looping an array of tables

How can I loop this array of tables?
TASK_CONFIG = {
[1] = {NAME = "1-a", COUNT = 10, REWARD = 1000},
[2] = {NAME = "4-b", COUNT = 10, REWARD = 6000},
[3] = {NAME = "3-a", COUNT = 15, REWARD = 2400},
}
I need something like:
for each ITEM in TASK_CONFIG
for each FIELD in ITEM
-- do something
next
next
The idea is looping every field, for example:
Looping every row and getting the values "name", "count", "reward"
for a, b in pairs(TASK_CONFIG) do
for c, d in pairs(b) do
-- print info / do something
end
end

Can't figure out this table arrangement

--The view of the table
local originalStats = {
Info = {Visit = false, Name = "None", Characters = 1},
Stats = {Levels = 0, XP = 0, XP2 = 75, Silver = 95},
Inventory = {
Hats = {"NoobHat"},
Robes = {"NoobRobe"},
Boots = {"NoobBoot"},
Weapons = {"NoobSword"}
}
}
local tempData = {}
--The arrangement here
function Module:ReadAll(player)
for k,v in pairs(tempData[player]) do
if type(v) == 'table' then
for k2, v2 in pairs(v) do
print(k2) print(v2)
if type(v2) == 'table' then
for k3, v3 in pairs(v2) do
print(k3) print(v3)
end
else
print(k2) print(v2)
end
end
else
print(k) print(v)
end
end
end
I'm sorry, but I can't seem to figure out how to arrange this 'ReadAll' function to where It'll show all the correct stats in the right orders.
The output is something like this:
Boots
table: 1A73CF10
1
NoobBoot
Weapons
table: 1A7427F0
1
NoobSword
Robes
table: 1A743D50
1
NoobRobe
Hats
table: 1A73C9D0
1
NoobHat
XP2
75
XP2
75
Levels
2
Levels
2
XP
0
XP
0
Here's a way to print all the elements without double or table reference values showing up.
As the name states, this function will print all the elements within a table, no matter how many nested tables there are inside it. I don't have a way to order them at the moment, but I'll update my answer if I find a way. You can also get rid of the empty spaces in the print line, I just used it so it would look neater. Let me know if it works.
function allElementsInTable(table)
for k,v in pairs(table) do
if type(table[k]) == 'table' then
print(k .. ":")
allElementsInTable(v)
else
print(" " .. k .. " = " .. tostring(v))
end
end
end
--place the name of your table in the parameter for this function
allElementsInTable(originalStats)
After more experimenting, I got this, if anyone wants it, feel free to use it.
tempData = { Info = {Visit = false, Name = 'None'},
Stats = {LVL = 0, XP = 0, Silver = 75},
Inventory = { Armors = {'BasicArmor'},
Weapons = {'BasicSword'} }
}
function Read()
for i, v in pairs(tempData['Info']) do
print(i..'\t',v)
end
----------
for i2, v2 in pairs(tempData['Stats']) do
print(i2..'\t',v2)
end
----------
for i3, v3 in pairs(tempData['Inventory']) do
print(i3..':')
for i4, v4 in pairs(v3) do
print('\t',v4)
end
end
end
Read()
Don't expect table's fields to be iterated with pairs() in some specific order. Internally Lua tables are hashtables, and the order of fields in it is not specified at all. It will change between runs, you can't have them iterated in the same order as they were filled.Only arrays with consecutive integer indices will maintain the order of their elements.

How can I implement a read-only table in lua?

I wrote an example.
function readOnly(t)
local newTable = {}
local metaTable = {}
metaTable.__index = t
metaTable.__newindex = function(tbl, key, value) error("Data cannot be changed!") end
setmetatable(newTable, metaTable)
return newTable
end
local tbl = {
sex = {
male = 1,
female = 1,
},
identity = {
police = 1,
student = 2,
doctor = {
physician = 1,
oculist = 2,
}
}
}
local hold = readOnly(tbl)
print(hold.sex)
hold.sex = 2 --error
It means that I can give access to the field of the table "tbl" but at the same time, I cannot change the value related to the field.
Now, the problem is that I wanna let all the nested tables own this read-only
property.How can I improve the "readOnly" method?
You just have to apply your readOnly function recursively to the inner table fields as well. You can do so on-access in the __index metamethod. You should also cache the readonly proxy tables that you create, otherwise any read access to inner tables (e.g. hold.sex) will create a new proxy table.
-- remember mappings from original table to proxy table
local proxies = setmetatable( {}, { __mode = "k" } )
function readOnly( t )
if type( t ) == "table" then
-- check whether we already have a readonly proxy for this table
local p = proxies[ t ]
if not p then
-- create new proxy table for t
p = setmetatable( {}, {
__index = function( _, k )
-- apply `readonly` recursively to field `t[k]`
return readOnly( t[ k ] )
end,
__newindex = function()
error( "table is readonly", 2 )
end,
} )
proxies[ t ] = p
end
return p
else
-- non-tables are returned as is
return t
end
end

Sorting Tables Twice in one Function - Lua

Want the function to sort the table by HP but if duplicate HPs then sorts by name. When i run this function it just groups the duplicate HPs together in no order by the name.
T = { {Name = "Mark", HP = 54, Breed = "Ghost"}, {Name = "Stan", HP = 24, Breed = "Zombie"}, {Name = "Juli", HP = 100, Breed = "Human"}, { HP = 100, Breed = "Human"} }
function(x, y) if x.Name == nil or y.Name == nil then return x.HP < y.HP else return x.Name < y.Name and x.HP < y.HP end end) end
Try this sort func:
function(x,y)
if x.Name == nil or y.Name == nil then
return x.HP < y.HP
else
return x.HP < y.HP or (x.HP == y.HP and x.Name < y.Name)
end
end
Since you always want differing HPs to be the primary sorting order (and name secondary), you want the HP check to come first in the or clause so that if it differs it'll skip any other checks and just determine based on HP.

Resources