How to iterate from last index to first in table - lua

bestSword = {
{name = 'www' , lvl = 35, atk = 38, npcPrice = 15000 , buyPrice = 0},
{name = 'bbb' , lvl = 40, atk = 40, npcPrice = 20000 , buyPrice = 0},
{name = 'eee' , lvl = 50, atk = 42, npcPrice = 25000 , buyPrice = 0},
{name = 'sss' , lvl = 55, atk = 43, npcPrice = 30000 , buyPrice = 0},
{name = 'aaa' , lvl = 60, atk = 44, npcPrice = 30000 , buyPrice = 0},
{name = 'qwe' , lvl = 70, atk = 46, npcPrice = 35000 , buyPrice = 0},
{name = 'asd' , lvl = 82, atk = 48, npcPrice = 60000 , buyPrice = 0}
}
I have this table, how can I iterate from last index to first? It should break depends from lvl. I just want to show this table from the best weapon. For example if Player have level 53, then I want to show only weapons for his lvl or lower. I need to show that from the best one (at top) its why I want to iterate from the last index. Could someone help?
EDIT:
Thanks for help. There is still a problem that I need this changed table later. It shows all fine but I need to buy all litems from this (changed) list later. So I must replace in some way this 2 tables. Is there any easy way to do that? I tried to remove elements from this table but it still not works.
Or its possible to make some map in Lua? It must be dynamic sized so i cant use table i guess. Something with key - value

A numeric for loop, counting down, is the best option:
local t = {2,4,6,8}
for i = #t, 1, -1 do
print(t[i])
end

Assuming that the table is not necessarily sorted into level order (unlike the example), we need to do two things:
Find which swords are in the level range
Sort them into descending order
Now the first one in the temporary table is the "best" sword.
Like this:
bestSword = {
{name = 'www' , lvl = 35, atk = 38, npcPrice = 15000 , buyPrice = 0},
{name = 'bbb' , lvl = 40, atk = 40, npcPrice = 20000 , buyPrice = 0},
{name = 'eee' , lvl = 50, atk = 42, npcPrice = 25000 , buyPrice = 0},
{name = 'sss' , lvl = 55, atk = 43, npcPrice = 30000 , buyPrice = 0},
{name = 'aaa' , lvl = 60, atk = 44, npcPrice = 30000 , buyPrice = 0},
{name = 'qwe' , lvl = 70, atk = 46, npcPrice = 35000 , buyPrice = 0},
{name = 'asd' , lvl = 82, atk = 48, npcPrice = 60000 , buyPrice = 0}
}
myLevel = 53 -- wanted level
-- temporary table
possible = { }
-- extract ones which are in range
for k, v in ipairs (bestSword) do
if v.lvl <= myLevel then
table.insert (possible, v)
end -- if
end -- for
if #possible == 0 then
print "No matching swords"
else
table.sort (possible, function (a, b) return a.atk > b.atk end )
bestSword = possible [1]
print ("Best sword is", bestSword.name, "lvl =", bestSword.lvl,
"atk = ", bestSword.atk)
end -- if
Or its possible to make some map in Lua? It must be dynamic sized so i cant use table i guess. Something with key - value
Tables in Lua are maps. Every table has key/value pairs. The one you are using there are simply numerically-keyed tables.
All tables are dynamically sized.

Related

Lua Table - Search for Items that starts with an Letter

i have this table
animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324
}
there i can search by a listed entry
for _,v in pairs(animals) do
if v.sname == "bunny" then
print(v.sname, v.name, v.size, v.size2, v.size3)
break
end
end
and get the result:
bunny bunny hase 4 8 9
Now i want to search in my table by starting with a single Letter, for example "b", that show me all the entries starting with the letter "b" to get the same result?
I found no Solution. May you can help me?
First: The table animals needs a trailing } ;-)
Put it in a Lua -i console and play around with...
>animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Now set a __call metamethod on same table
>setmetatable(animals,{__call=function(tab,...)
local args={...}
for key, value in pairs(tab) do
if value.sname:find(args[1],1) then print(key,'=',value.sname) end
end
end})
table: 0x565c4a00
-- Lets try it once
>animals('b')
1 = bunny
-- Next one
>animals('c')
3 = cow
-- Last one
>animals('m')
2 = mouse
Using metatables holds your stuff together.
Another fine place is the __index metamethod that can hold all functions you need for that table and can be used like the string functions on a string.
( Like: value.sname:find(args[1],1) )
This leads to the heart of what find should do.
In first example it looks in whole sname for a matching pattern.
Check the Lua patterns what also can be useful.
Maybe a ^ only for the begining sounds smart?
So construct the find pattern: '^'..args[1]
...and use more than one letter if you have a cow, crow, frog and fish in your animals.
Example with function name find in __index
>animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Place a find function into __index
>setmetatable(animals,{__index={find=function(tab,...)
local args={...}
for key, value in pairs(tab) do
if value.sname:find('^'..args[1]) then print(key,'=',value.sname) end
end
end}})
table: 0x565c3db0
-- first
>animals:find('c')
3 = cow
-- next
>animals:find('m')
2 = mouse
-- last
>animals:find('b')
1 = bunny
If you like to print all key values then extend the print() in find().
Stop, i found an issue....
Look here - i prefer the first solution:
animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Now set a __call metamethod on same table
setmetatable(animals,{__call=function(tab,...)
local args={...}
for v,k in pairs(tab) do
if k.sname:find(args[1],1) then print(v,'=',k.sname) end
end
end})
-- Search Entries with Start U.....
-- there should be no result, but....
animals('u')
i get the Result:
1 = bunny
2 = mouse
that should not be the result!

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

Mean/median/mode from complex table in lua

Thank you for all the support with lua, I'm very new and my application is working nicely so far.
I've made an app that will take in a few thousand numbers for different items. I'm trying to find the Mean/Media/Mode for each item, I've been able to do this for a single item, but not for all items.
Here is my table structure:
for i = 0, 1500 do
local e = {}
e.seller,
e.buyer,
e.itemName,
e.soldAmount = GetSoldAmount(FromMember(i))
table.insert(allSalesTempTable, e)
end
Table output format
[1] =
{
["itemName"] = [[Salad]]
["buyer"] = [[#Mike]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
},
[2] =
{
["itemName"] = [Pizza]
["buyer"] = [[#James]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
},
[3] =
{
["itemName"] = [Salad]
["buyer"] = [[#Frank]],
["eventType"] = 15,
["soldAmount"] = 75,
["seller"] = [[#Sarah]],
},
[4] ...
},
Then I'm trying to send the table/array to this mean function
stats={}
-- Get the mean value of a table
function stats.mean( t )
local sum = 0
local count= 0
local tempTbl = {}
(This is completely not going to work, but its what I'm trying so far)
for k,v in pairs(t) do tempTbl[k] = v
if v.itemName == tempTbl.itemName then
sum = sum + v.soldAmount
count = count + 1
end
end
return (sum / count)
end
--- To get the function started
stats.mean(e)
Here is where I'm getting fuzzy, Not sure if I can add the MEAN while collecting the data into the first temp table, or if it needs to be re-calculated after I have all the data?
If it needs to be done after, then my stats.mean(e) needs a way to insert it?
I'm trying to get this output:
[1] =
{
["itemName"] = [[Salad]]
["buyer"] = [[#Mike]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
["mean"] = 112.5 - New Insert somehow
},
[2] =
{
["itemName"] = [Pizza]
["buyer"] = [[#James]],
["eventType"] = 15,
["soldAmount"] = 150,
["seller"] = [[#Sarah]],
["mean"] = 150 - New Insert somehow
},
[3] =
{
["itemName"] = [Salad]
["buyer"] = [[#Frank]],
["eventType"] = 15,
["soldAmount"] = 75,
["seller"] = [[#Sarah]],
["mean"] = 112.5 - New Insert somehow
},
[4] ...
},
I've been working on this problem for a few days, After I see how to adjust my format for the mean and insert into the existing table I'll be able to figure out mean/min/max/median/mode easy enough.

Lua - Table in a Table Printing and Sorting

T = {
{Name = "Mark", HP = 54, Breed = "Ghost"},
{Name = "Stan", HP = 24, Breed = "Zombie"},
{Name = "Juli", HP = 100, Breed = "Human"}},
Questions:
How would I Print just the names?
and
How can I sort it by HP?
You need to iterate over the table by using either the pairs or ipairs function to print the name. ipairs iterates from 1 to N (numeric indices only), while pairs iterates over every element, in no defined order.
> T = { {Name = "Mark", HP = 54, Breed = "Ghost"}, {Name = "Stan", HP = 24, Breed = "Zombie"}, {Name = "Juli", HP = 100, Breed = "Human"}}
> for _,t in ipairs(T) do print(t.Name) end
Mark
Stan
Juli
Then you can use the table.sort function to sort the table in-place:
> table.sort(T, function(x,y) return x.HP < y.HP end)
> for _,t in ipairs(T) do print(t.Name, t.HP) end
Stan 24
Mark 54
Juli 100
The second argument to table.sort is a comparison function of your choice; in this case, we only wanted to compare the HP values.

Resources