Using Data From Tables

Posted by Uchida on Sun 21 Apr 2024 09:22 AM — 7 posts, 12,911 views.

#0
Hi, I made a table and when i

table.foreach (t, print)

I get :

1 Michael - Name 2343 - Gold
2 Loo - Name 256 - Gold
3 James - Name 405 - Gold
4 Sam - Name 1202 - Gold
5 Beth - Name 0 - Gold
6 Hogan - Name 0 - Gold
7 Alan - Name 0 - Gold
8 John - Name 0 - Gold
9 Tammy - Name 0 - Gold
10 Elvin - Name 0 - Gold

How do i ignore the 0 values and send the rest to a channel listing from biggest number to smallest and list the percentage for each of them?

wanted result:
Michael (55.70%) , Sam (28.57%), James (9.63%), Loo (6.08%)

Thanks!!
Amended on Sun 21 Apr 2024 09:24 AM by Uchida
Australia Forum Administrator #1
Can you show more of your code? Are the table entries just strings?

The simple way would be to iterate, like this:


for k, v in ipairs (t) do
  if v.gold ~= 0 then
     print (v)
  end -- if they have gold
end -- of for



In this code k is the key and v is the value, for each table entry.
#2
Hi Nick! Thank you for your reply!

This is currently my code which i learnt from your 3 trigger style.

<triggers>
<trigger
enabled="y"
group="TEST"
match="^(.*?) \- Name (.*?) \- Gold$"
name="inventory_line"
regexp="y"
send_to="12"
sequence="50"
>
<send>
table.insert (members, "%0" ) -- add inventory item to our table

</send>
</trigger>
<trigger
group="TEST"
match="startgoldreport"
name="inventory_starter"
send_to="12"
sequence="100"
>
<send>members = {}

EnableTrigger ("inventory_starter", false)
EnableTrigger ("inventory_line", true)
EnableTrigger ("inventory_stopper", true)
</send>
</trigger>
<trigger
enabled="y"
group="TEST"
match="gold report end"
name="inventory_stopper"
send_to="12"
sequence="40"
>
<send>Note("Stopping")

EnableTrigger ("inventory_line", false)
EnableTrigger ("inventory_stopper", false)
EnableTrigger ("inventory_starter", true)

table.foreach (members, print)

</send>
</trigger>
</triggers>

-----------------------------------------------

This is what i get when i "generate to show a gold report" that is from another plugin.

startgoldreport
Michael - Name 2343 - Gold
Sam - Name 1202 - Gold
James - Name 405 - Gold
Loo - Name 256 - Gold
John - Name 0 - Gold
gold report end

I don't want it to just print. I want to be able to :
Send("chat Michael(55.70%) , Sam(28.57%), James(9.63%), Loo(6.08%)")

Is it possible?
Thank you very much!
Amended on Mon 22 Apr 2024 07:11 AM by Uchida
Australia Forum Administrator #3
Using your test data as an example:




-- test data
members = {
"Michael - Name 2343 - Gold",
"Sam - Name 1202 - Gold",
"James - Name 405 - Gold",
"Loo - Name 256 - Gold",
"John - Name 0 - Gold"
}

myList = { }  -- table for outputting
totalGold = 0

-- find total gold
for k, v in ipairs (members) do
  name, gold = v:match ("^([^ ]+) %- Name (%d+) %- Gold")
  if gold then
    totalGold = totalGold + gold
  end -- if
end -- for

-- make table of people who have more than zero gold
for k, v in ipairs (members) do
  name, gold = v:match ("^([^ ]+) %- Name (%d+) %- Gold")
  if name and tonumber (gold) ~= 0 then
    table.insert (myList, string.format ("%s(%0.2f%%)", name, gold / totalGold * 100))
  end -- if they have some gold
end -- for

-- send results
Send ("chat " .. table.concat (myList, ", "))


This outputs:


chat Michael(55.71%), Sam(28.58%), James(9.63%), Loo(6.09%) 


So basically replace:


table.foreach (members, print)


with the above code, omitting my test data.
Amended on Mon 22 Apr 2024 07:02 AM by Nick Gammon
#4
Hi Nick! Thanks again! I tried put this code into alias and run it but it occurred an error. Can this work from alias?
It also did not work when i replaced table.foreach (members, print) in the last trigger with it. :(

<aliases>
<alias
match="tabletest"
enabled="y"
group="TEST"
send_to="12"
sequence="100"
>
<send>-- test data
members = {
"Michael - Name 2343 - Gold",
"Sam - Name 1202 - Gold",
"James - Name 405 - Gold",
"Loo - Name 256 - Gold",
"John - Name 0 - Gold"
}

myList = { } -- table for outputting
totalGold = 0

-- find total gold
for k, v in ipairs (members) do
name, gold = v:match ("^([^ ]+) %- Name (%d+) %- Gold")
if gold then
totalGold = totalGold + gold
end -- if
end -- for

-- make table of people who have more than zero gold
for k, v in ipairs (members) do
name, gold = v:match ("^([^ ]+) %- Name (%d+) %- Gold")
if name and tonumber (gold) ~= 0 then
table.insert (myList, string.format ("%s(%0.2f%%)", name, gold / totalGold * 100))
end -- if they have some gold
end -- for

-- send results
Send ("chat " .. table.concat (myList, ", "))</send>
</alias>
</aliases>


------------------------------

Error:
Run-time error
World: MyMud
Immediate execution
[string "Alias: "]:25: invalid option '%)' to 'format'
stack traceback:
[C]: in function 'format'
[string "Alias: "]:25: in main chunk
Amended on Mon 22 Apr 2024 08:06 AM by Uchida
Australia Forum Administrator #5
Ah yes, well inside a trigger or alias the % symbol has a special meaning, eg. %1 is wildcard 1 and %2 is wildcard 2 and so on. To literally put a % inside (as I did in the string.format) you need to double it, so this works:


<aliases>
  <alias
   match="tabletest"
   enabled="y"
   group="TEST"
   send_to="12"
   sequence="100"
  >
  <send>-- test data
members = {
"Michael - Name 2343 - Gold",
"Sam - Name 1202 - Gold",
"James - Name 405 - Gold",
"Loo - Name 256 - Gold",
"John - Name 0 - Gold"
}

myList = { }  -- table for outputting
totalGold = 0

-- find total gold
for k, v in ipairs (members) do
  name, gold = v:match ("^([^ ]+) %%- Name (%%d+) %%- Gold")
  if gold then
    totalGold = totalGold + gold
  end -- if
end -- for

-- make table of people who have more than zero gold
for k, v in ipairs (members) do
  name, gold = v:match ("^([^ ]+) %%- Name (%%d+) %%- Gold")
  if name and tonumber (gold) ~= 0 then
    table.insert (myList, string.format ("%%s(%%0.2f%%%%)", name, gold / totalGold * 100))
  end -- if they have some gold
end -- for

-- send results
print ("chat " .. table.concat (myList, ", "))</send>
  </alias>
</aliases>


Template:pasting
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.


I changed Send to print near the bottom but you can change that back when you are happy it works.
#6
It works perfectly now!

Thanks a lot Nick!

I had been cracking my brain over this for couple of days!!

*Thumbs!!