Is there any way of getting all the non-nil parameters / properties
of an object? I found this: getmetadata(self.xxxx) and i am looking for something like: getalldata(self).
I'm currently working on a project where lua is involved. Unfortunately, there is no complete reference and i have to use precompiled stuff.
I hope you are able to understand what I am trying to say.
I'm going to assume that when you are referring to "objects" you are meaning "lua tables with an __index metatable pointing to other tables". If that is not the case, this answer will not help you.
If your object structure is made with tables (this is, all __indexes are tables) then you can "parse them up" to obtain all the properties and inherited properties.
If you have any function as __index then what you ask is impossible; there's no way to get the "list of values for which a function returns a non-nil value".
In the first case, the code would look like this:
function getAllData(t, prevData)
-- if prevData == nil, start empty, otherwise start with prevData
local data = prevData or {}
-- copy all the attributes from t
for k,v in pairs(t) do
data[k] = data[k] or v
end
-- get t's metatable, or exit if not existing
local mt = getmetatable(t)
if type(mt)~='table' then return data end
-- get the __index from mt, or exit if not table
local index = mt.__index
if type(index)~='table' then return data end
-- include the data from index into data, recursively, and return
return getAllData(index, data)
end
But remember, if any of your __indexes is a function, there is no way to get all the properties; at least not from Lua.
I wrote my own printObject code.. here it is
function printObj(obj, hierarchyLevel)
if (hierarchyLevel == nil) then
hierarchyLevel = 0
elseif (hierarchyLevel == 4) then
return 0
end
local whitespace = ""
for i=0,hierarchyLevel,1 do
whitespace = whitespace .. "-"
end
io.write(whitespace)
print(obj)
if (type(obj) == "table") then
for k,v in pairs(obj) do
io.write(whitespace .. "-")
if (type(v) == "table") then
printObj(v, hierarchyLevel+1)
else
print(v)
end
end
else
print(obj)
end
end
This is the opposite approach then the post before used.
Go through all key value pairs in the table. If the value of one index is a table, go through this table.
This solution will not get the upwards metatables like the other post did
I believe objects are just a table, so you should be able to iterate over the properties as any other table:
for i,v in ipairs(your_object) do body end
Related
I'm very new in using Cognos report studio and trying to filter some of the values and replace them into others.
I currently have values that are coming out as blanks and want to replace them as string "Property Claims"
what i'm trying to use in my main query is
CASE WHEN [Portfolio] is null
then 'Property Claims'
ELSE [Portfolio]
which is giving me an error. Also have a different filter i want to put in to replace windscreen flags to a string value rather than a number. For example if the flag is 1 i want to place it as 'Windscreen Claims'.
if [Claim Windscreen Flag] = 1
then ('Windscreen')
Else [Claim Windscreen Flag]
None of this works with the same error....can someone give me a hand?
Your first CASE statement is missing the END. The error message should be pretty clear. But there is a simpler way to do that:
coalesce([Portfolio], 'Property Claims')
The second problem is similar: Your IF...THEN...ELSE statement is missing a bunch of parentheses. But after correcting that you may have problems with incompatible data types. You may need to cast the numbers to strings:
case
when [Claim Windscreen Flag] = 1 then ('Windscreen')
else cast([Claim Windscreen Flag], varchar(50))
end
In future, please include the error messages.
it might be syntax
IS NULL (instead of = null)
NULL is not blank. You might also want = ' '
case might need an else and END at the bottom
referring to a data type as something else can cause errors. For example a numeric like [Sales] = 'Jane Doe'
For example (assuming the result is a string and data item 2 is also a string),
case
when([data item 1] IS NULL)Then('X')
when([data item 1] = ' ')Then('X')
else([data item 2])
end
Also, if you want to show a data item as a different type, you can use CAST
I am writing an Excel VBA program that validates a school course schedule. A key component is a global dictionary object that keeps track of the course number (the key) and the number of times that course is scheduled (the item). I have successfully created and loaded the dictionary. I'm trying to lookup the value associated with the course key, but have been unable to do so using the one-line examples I've found at this site. I'd like to use this line of code:
intCourseCnt = gdicCourses("BAAC 100")
or
intCourseCnt = gdicCourses.Item("BAAC 100")
but neither work (actually, the "BAAC 100" part is a string variable, but it won't even work if I hardcode a course in.) Instead, I have to use the kludgy loop code below to lookup the course count:
Private Function Check_Course_Dup_Helper(strCourse As String) As Boolean
Dim k As Variant
Check_Course_Dup_Helper = False
' Read thru dictionary. Look to see if only 1 occurrence then jump out.
For Each k In gdicCourses.Keys
If k = strCourse Then
If gdicCourses.Item(k) = 1 Then
Check_Course_Dup_Helper = True
Exit Function
End If
Exit Function
End If
Next
End Function
Is there a way to rewrite this so that I can lookup of the item value without the loop?
Thank you.
Thanks for the prompt replies. Answers below:
David, the gdicCourses("BAAC 100") code value while the program is running is "empty" which makes the receiving variable equal to 0. The result is the same if I use strCourse variable. Also, the dictionary populating code is shown below. I do not believe it is a problem because I can correctly access the values elsewhere in the program where For-Each-Next loops that use a range variable are employed. Whitespace and non-printable characters are not present.
My guess is that I need to use a range to reference the position in the dictionary rather than a string. I've tried pretty much every combination of this that I can think of, but the value is still "empty".
Set gdicCourses = New Scripting.Dictionary
For Each c In Worksheets("Tables").Range("combined_courses").Cells
If Not (gdicCourses.Exists(c)) Then
gdicCourses.Add c, (Application.WorksheetFunction.CountIF(Range("MWF_Table_Full"), c
(Application.WorksheetFunction.CountIf(Range("TTh_Table_Full"), c)))
End If
Next
So let's say I have a string called Hi there.
I am currently using
m:match("^(%S+)")
to get just Hi from the string, now all I need to do is just get "there" from the string but I have no idea how.
Checkout this page: http://lua-users.org/wiki/SplitJoin
There are numerous ways to split words in a string on whitespace.
This one seems like it might be a good fit for your problem:
function justWords(str)
local t = {} -- create an empty table
-- create a function to insert a word into the table
local function helper(word) table.insert(t, word) return "" end
-- grab each word in the string and pass it to `helper`
if not str:gsub("%w+", helper):find"%S" then return t end
end
table = justWords(example)
table[1] -- hi
table[2] -- there
table[3] -- nil
There is a simple cursor, which has 260 records. Inside the loop not only print but update some tables. There is not only code, but explanation
/*Declare cursor for read only*/
DECLARE crsr_one CURSOR FOR
SELECT a,b,c,d
FROM table_name
WHERE a>=100
for read only
OPEN crsr_one /*open cursor*/
DECLARE #a,#b,#c,#d /*declare loop variables*/
while (1=1) /*start while loop*/
BEGIN
FETCH crsr_one into #a,#b,#c,#d /*fetch into variable */
IF (##sqlstatus = 2) /*Break if no more records*/
break
/*some other code with select and update table*/
print "%1! %2! %3! %4!", #a,#b,#c,#d /*Print variables*/
END
The problem is:
In the while loop it became infinitive and brings the same data.
Any idea why and how to correct it?
Your code looks good (except that the syntax for the DECLARE is invalid).
If the loop doesn't break on ##sqlstatus = 2, then the obvious question is: what value does it have? It can also be '1', indicating an error. To find out, print the value.
To be fully correct you should therefor also test for ##sqlstatus = 1. The easiest way to do this is to test for ##sqlstatus != 0 which covers both values 1 and 2.
I have a string and want to check if in the workspace exist any variable with the same name. In the workspace I have also many structures M.N.O M.N.N M.N.M etc. I can only check if there exist a variable with the name M. How to go deeper into this structure?
I tried:
exist('M.N')
YesNo = any(strcmp(who,'M.N.O'))
evalin('base','exist(''M.N.O'',''var'')')
all give me the same problem so I am stuck.
You can use isfield to check if a variable has a specific field. See the link for examples!
For your example, you'd need:
isfield(M,'N')
and if true, you can go deeper:
isfield(M.N,'O')
Notice that
isfield(M,'N.O')
won't work ;)
One option: write a recursive function to expand structures down to their leaf fields, appending the fields to a list.
(untested, conceptual code - probably won't work quite right as is)
function varlist = getStructFields(var,varlist)
if isstruct(var)
fn = fieldnames(var);
varlist = vertcat(varlist,fn); %# append fields to the list
for field = fn' %# ' create row vector; iterate through fields
varlist = getStructFields(var.(char(field)), varlist); %# recursion here
end
end
end
Then you can use the any(strcmp(who,'M.N.O')) check you already came up with.