Frank Barknecht wrote:
Hallo, robcanning hat gesagt: // robcanning wrote:
i add a list to a table with:
-- "insert [list]" into 1st inlet: function M:in_1_insert(list) table.insert(self.mydata, list) end
then i search the table for the pattern "score = 1" and ask it to print the lines containing the matched pattern
-- what to do on "scores" into 1st inlet: function M:in_1_scores() for i, v in ipairs(self.mydata) do if string.match(v, "score = 1", 1, true) then self:outlet(1, "list", v) end end end
the problem is that the string.match is expecting a string and getting a table and i'm not sure how to fix this - i thought the ipairs was iterating the table into a string but its not.
here is the error from pd: [string "rob2"]:19: bad argument #1 to 'match' (string expected, got table)
Okay, that's an issue with the general kinds of types in Lua, which can be a bit confusing at first. Basically in Lua/Pd you will have to deal with these three types: numbers, strings and tables. (There are more types e.g. functions.)
Now the first two are easy: numbers are 1, 2, 3.141, ... and strings are "this" and "that, too". Tables however are a bit trickier: For one they can be like lists in Pd:
counts = {1, 2, 3, "four", "and five"} print(counts[4]) -- prints: "four" print(type(counts[4])) -- it's a string
These kinds of tables which are indexed with numbers are also called "arrays" in Lua parlance. In Pd they are called lists.
Arrays also can contain other arrays and tables:
counts = {1, 2, 3, "four", "and five", {"x", "y", "z"} }
But the outlet functions in pdlua generally only work with flat arrays! So you first need to convert your data to a flat array using a pairs/ipairs iterator for example.
In the "in_*_something(args)" methods, args generally is an array as well (except for the bang, float and symbol methods).
The self.mydata table in rob2.lua is not flat, so it needs to be made flat like that.
self.mydata also is a key/value table (containing flat arrays indexed by string or numeric keys).
Tables in Lua can be key/value containers, which is something, Pd doesn't have directly:
veggies = {apples = 4, potatoes = 10} print(veggies.apples) -- prints: 4
And to make things worse, tables can contain tables:
stuff = {counts, veggies} print(stuff[2].potatoes) -- prints: 10
or even stuff like functions:
stuff.func = function() -- does nothing end
for k,v in pairs(stuff) do print (k,v) end
So, you see in that part here:
for i, v in ipairs(self.mydata) do if string.match(v, "score = 1", 1, true) then self:outlet(1, "list", v) end end
You have one "v" which is expected to be a string in string.match(), and another which is expected to be a table/array in self:outlet()!
This won't work, and the error message of Lua tells you, that "v" (the values of self.mydata) is a table, so it won't work in string.match()
I hope this clears it up a bit.
Now for the fix: You can convert a (flat) list/array to a string with table.concat(somelist, sep) where sep is the separator. If you use a space for sep, you can use
string.match(table.concat(v, " "), "score = 1")
or a bit better:
string.find(table.concat(v, " "), "score = 1", 1, true)
Better because string.find doesn't try to build and return a string, which you wouldn't be interested in anyhow.
Ciao
ok great - i got the hang of that now i think
now what i cant figure out is how to pass arguments to the code from a pd message
ok, so this code finds all the scores with a value greater than one and sends them to outlet one when given the message [greaterthan(
function M:in_1_greaterthan() for i, v in ipairs(self.mydata) do if tonumber(string.match(table.concat(v, " "), "score=(%d+)")) > 1 then self:outlet(1, "", v) end end end
now i want to be able to send the message [greaterthan score 3(
so in the code where it says "score=(%d+)")) - i need "score" to be variable from second part of the message the ">1" needs to be a variable from the 3rd part of the message
i know its somewhere within the () below but i cant seem to get it right function M:in_1_greaterthan()
thanks,
rob c