How to manipulate with incremental names of fields?
For example:
myBitmapField1
myBitmapField2
myBitmapField3
...
Is a way to add them to FieldManager in a way like this or similar:
int i = 0;
while (i < 1000)
{
i = i + 1;
if (myCounter == i)
myVerticalFieldManager.add(_myBitmapField[i]);
}
...
There is a way to manipulate with incremental names of file names like this:
myBitmapField.setBitmap(Bitmap.getBitmapResource("a" + myCounter + ".png"));
But I need to manipulate with names of fields ! How could I do that?
Ideally, don't - use an array (or possibly a List) instead. If you have to use names, create an appropriate Map (e.g. a HashMap) from names to values.
While you can access fields using reflection - at least in "normal" Java - it would be a poor design here. You've got multiple related values, so use a collection... it's as simple as that.
If I understand correctly, you want to access the fields in a manager by name. You can instead access them by field position. Perhaps that will do for what you need.
Related
Reading the injected comments in the Code Snippet should give enough context.
--| Table |--
QuestData = {
["QuestName"]={
["Quest Descrip"]={8,1686192712},
["Quest Descrip"]={32,1686193248},
["Quest Descrip"]={0,2965579272},
},
}
--| Code Snippet |--
--| gets QuestName then does below |--
if QuestName then
-- (K = QuestName) and (V = the 3 entries below it in the table)
for k,v in pairs(QuestData) do
-- Checks to make sure the external function that obtained the QuestName matches what is in the table before cont
if strlower(k) == strlower(QuestName) then
local index = 0
-- Iterates over the first two pairs - Quest Descrip key and values
for kk,vv in pairs(v) do
index = index + 1
end
-- Iterates over the second two pairs of values
if index == 1 then
for kk,vv in pairs(v) do
-- Sends the 10 digit hash number to the function
Quest:Function(vv[2])
end
end
end
end
end
The issue I'm running into is that Lua will only pick up one of the numbers and ignore the rest. I need all the possible hash numbers regardless of duplicates. The QuestData table ("database") has well over 10,000 entries. I'm not going to go through all of them and remove the duplicates. Besides, the duplicates are there because the same quest can be picked up in more than one location in the game. It's not a duplicate quest but it has a different hash number.
Key is always unique. It is the point of the key, that the key is pointing to unique value and you can't have more keys with same name to point different values. It is by definition by Lua tables.
It is like if you would want to have two variables with same name and different content. It does not make sense ...
The table type implements associative arrays. [...]
Like global variables, table fields evaluate to nil if they are not initialized. Also like global variables, you can assign nil to a table field to delete it. That is not a coincidence: Lua stores global variables in ordinary tables.
Quote from Lua Tables
Hashing in Lua
Based on comments, I update the answer to give some idea about hashing.
You are using hashing usually in low-level languages like C. In Lua, the associative arrays are already hashed somehow in the background, so it will be overkill (especially using SHA or so).
Instead of linked lists commonly used in C, you should just construct more levels of tables to handle collisions (there is nothing "better" in Lua).
And if you want to have it fancy set up some metatables to make it somehow transparent. But from your question, it is really not clear how your data look like and what you really want.
Basically you don't need more than this:
QuestData = {
["QuestName"]={
["Quest Descrip"]={
{8,1686192712},
{32,1686193248},
{0,2965579272},
},
},
}
As Jakuje already mentioned table keys are unique.
But you can store both as a table member like:
QuestData = {
-- "QuestName" must be unique! Of course you can put it into a table member as well
["QuestName"]={
{hash = "Quest Descrip", values = {8,1686192712} },
{hash = "Quest Descrip", values = {32,1686193248} },
{hash = "Quest Descrip", values = {0,2965579272} }
}
}
I'm sure you can organize this in a better way. It looks like a rather confusing concept to me.
You've said you can't "rewrite the database", but the problem is the QuestData table doesn't hold what you think it holds.
Here's your table:
QuestData = {
["QuestName"]={
["Quest Descrip"]={8,1686192712},
["Quest Descrip"]={32,1686193248},
["Quest Descrip"]={0,2965579272},
},
}
But, this is actually like writing...
QuestData["Quest Descrip"] = {8,1686192712}
QuestData["Quest Descrip"] = {32,1686193248}
QuestData["Quest Descrip"] = {0,2965579272}
So the second (and then, third) values overwrite the first. The problem is not that you can't access the table, but that the table doesn't contain the values any more.
You need to find a different way of representing your data.
I have a field which value is an array of strings.
Example: Mom, dad, son, etc.
It is possible to repeat a link with those values?
Example:
Mom
dad
son
And when I click on the link to have a href=www."fieldvalue".com.
EDIT: it is not vector, it is Array.
Create your repeat control. For the value add in your field name. Something like :
document1.getItemValue("myMultiValueField")
I THINK that should repeat your field assuming it is a real multi-value. The comma deliminated string would require more work. So I'm not talking about that...
Make sure the collection name / var name of the repeat is something like "rowData"
rowData should then be a String.
Drop a link control inside the repeat.
Compute the label to be simple "rowData". (no quotes in the code)
Compute the URL - which I THINK is "value" in all properties of the link
That's just javaScript so you should be able to do something like:
return "http://" + rowData + ".com"
That's rough - you'll have to play with it but if I follow you correctly should work.
For a comma deliminated String... in the repeat control you'd need to use SSJS or #functions to break that into an array so the repeat can work on it.
In your repeat you'll need to map the value attribute to the Vector and set a var property, which is how you will reference each element. Note: a comma-separated string is a single value, and a repeat requires multiple values. So you'll need to convert it to a Vector or some other multi-value object.
Within the repeat you can use any other control and compute the value as you would elsewhere. To access each element in your repeat control's source (i.e. each String in your Vector, in this case), use the variable name you've defined in the var property.
I know of:
http://lua-users.org/wiki/SimpleLuaApiExample
It shows me how to build up a table (key, value) pair entry by entry.
Suppose instead, I want to build a gigantic table (say something a 1000 entry table, where both key & value are strings), is there a fast way to do this in lua (rather than 4 func calls per entry:
push
key
value
rawset
What you have written is the fast way to solve this problem. Lua tables are brilliantly engineered, and fast enough that there is no need for some kind of bogus "hint" to say "I expect this table to grow to contain 1000 elements."
For string keys, you can use lua_setfield.
Unfortunately, for associative tables (string keys, non-consecutive-integer keys), no, there is not.
For array-type tables (where the regular 1...N integer indexing is being used), there are some performance-optimized functions, lua_rawgeti and lua_rawseti: http://www.lua.org/pil/27.1.html
You can use createtable to create a table that already has the required number of slots. However, after that, there is no way to do it faster other than
for(int i = 0; i < 1000; i++) {
lua_push... // key
lua_push... // value
lua_rawset(L, tableindex);
}
I'm trying to figure out the best approach to display combined tables based on matching logic and input search criteria.
Here is the situation:
We have a table of customers stored locally. The fields of interest are ssn, first name, last name and date of birth.
We also have a web service which provides the same information. Some of the customers from the web service are the same as the local file, some different.
SSN is not required in either.
I need to combine this data to be viewed on a Grails display.
The criteria for combination are 1) match on SSN. 2) For any remaining records, exact match on first name, last name and date of birth.
There's no need at this point for soundex or approximate logic.
It looks like what I should do is extract all the records from both inputs into a single collection, somehow making it a set on SSN. Then remove the blank ssn.
This will handle the SSN matching (once I figure out how to make that a set).
Then, I need to go back to the original two input sources (cached in a collection to prevent a re-read) and remove any records that exist in the SSN set derived previously.
Then, create another set based on first name, last name and date of birth - again if I can figure out how to make a set.
Then combine the two derived collections into a single collection. The collection should be sorted for display purposes.
Does this make sense? I think the search criteria will limit the number of record pulled in so I can do this in memory.
Essentially, I'm looking for some ideas on how the Grails code would look for achieving the above logic (assuming this is a good approach). The local customer table is a domain object, while what I'm getting from the WS is an array list of objects.
Also, I'm not entirely clear on how the maxresults, firstResult, and order used for the display would be affected. I think I need to read in all the records which match the search criteria first, do the combining, and display from the derived collection.
The traditional Java way of doing this would be to copy both the local and remote objects into TreeSet containers with a custom comparator, first for SSN, second for name/birthdate.
This might look something like:
def localCustomers = Customer.list()
def remoteCustomers = RemoteService.get()
TreeSet ssnFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.ssn <=> c2.ssn}))
ssnFilter.addAll(localCustomers)
ssnFilter.addAll(remoteCustomers)
TreeSet nameDobFilter = new TreeSet(new ClosureComparator({c1, c2 -> c1.firstName + c1.lastName + c1.dob <=> c2.firstName + c2.lastName + c2.dob}))
nameDobFilter.addAll(ssnFilter)
def filteredCustomers = nameDobFilter as List
At this point, filteredCustomers has all the records, except those that are duplicates by your two criteria.
Another approach is to filter the lists by sorting and doing a foldr operation, combining adjacent elements if they match. This way, you have an opportunity to combine the data from both sources.
For example:
def combineByNameAndDob(customers) {
customers.sort() {
c1, c2 -> (c1.firstName + c1.lastName + c1.dob) <=>
(c2.firstName + c2.lastName + c2.dob)
}.inject([]) { cs, c ->
if (cs && c.equalsByNameAndDob(cs[-1])) {
cs[-1].combine(c) //combine the attributes of both records
cs
} else {
cs << c
}
}
}
I'm a little stumped on this one. Anyone have any ideas? I'll try to lay out the example as brief as possible.
Creating Silverlight 3.0 application against SQL 2005 database. Using RIA Services and Entity Framework for data access.
I need to be able to populate a grid against a table. However, my grid UI and my table structure is different. Basically my grid needs to turn rows into columns (like a PIVOT table). Here are my challenges / assumptions
I have no idea until runtime which columns I will have on the grid.
Silverlight 3 only supports binding to properties
Silverlight 3 does not allow you to add a row to the grid and manually populate data.
As we all know, Silverlight does not have the System.Data (mainly DataTable) namespace
So, how do I create an object w/ dynamic properties so that I can bind to the grid. Every idea I've had (multi-dimensional arrays, hash tables, etc.) fall apart b/c SL needs a property to bind to, I can't manually add/fill a data row, and I can't figure out a way to add dynamic properties. I've seen an article on a solution involving a linked list but I'm looking for a better alternative. It may come down to making a special "Cody Grid" which will be a bunch of text boxes/labels. Doable for sure but I'll lose some grid functionality that users expect
The ONLY solution I have been able to come up is to create a PIVOT table query in SQL 2005 and use an entity based on that query/view. SQL 2008 would help me with that. I would prefer to do it in Silverlight but if that is the last resort, so be it. If I go the PIVOT route, how do I implement a changing data structure in Entity Framework?
Data Sample.
Table
Name Date Value
Cody 1/1/09 15
Cody 1/2/09 18
Mike 1/1/09 20
Mike 1/8/09 77
Grid UI should look like
Name 1/1/09 1/2/09 1/3/09 .... 1/8/09
Cody 15 18 NULL NULL
Mike 20 NULL NULL 77
Cody
My team came up with a good solution. I'm not sure who deserves the credit but it's somewhere in google land. So far it works pretty good.
Essentially the solution comes down to using reflection to build a dynamic object based on this dynamic data. The function takes in a 2-dimensional array and turns it into a List
object with properties that can be bound. We put this process in a WCF Service and it seems to do exactly what we need so far.
Here is some of the code that builds the object using Reflection
AppDomain myDomain = AppDomain.CurrentDomain;
AssemblyName myAsmName = new AssemblyName("MyAssembly");
AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAsmName.Name);
TypeBuilder myType = myModule.DefineType("DataSource", TypeAttributes.Public);
string columnName = "whatever";
for (int j = 0; j <= array.GetUpperBound(1); j++)
{
Type properyType = typeof(T);
FieldBuilder exField = myType.DefineField("_" + "columnName" + counter, properyType, FieldAttributes.Private);
//The following line is where I’m passing columnName + counter and getting errors with some strings but not others.
PropertyBuilder exProperty = myType.DefineProperty(columnName + counter.ToString(), PropertyAttributes.None, properyType, Type.EmptyTypes);
//Get
MethodBuilder exGetMethod = myType.DefineMethod("get_" + "columnName" + counter, MethodAttributes.Public, properyType, Type.EmptyTypes); ILGenerator getIlgen = exGetMethod.GetILGenerator();
//IL for a simple getter:
//ldarg.0
//ldfld int32 SilverlightClassLibrary1.Class1::_Age
//ret
getIlgen.Emit(OpCodes.Ldarg_0);
getIlgen.Emit(OpCodes.Ldfld, exField);
getIlgen.Emit(OpCodes.Ret);
exProperty.SetGetMethod(exGetMethod);
//Set
MethodBuilder exSetMethod = myType.DefineMethod("set_" + "columnName" + counter, MethodAttributes.Public, null, new Type[] { properyType }); ILGenerator setIlgen = exSetMethod.GetILGenerator();
//IL for a simple setter:
//ldarg.0
//ldarg.1
//stfld int32 SilverlightClassLibrary1.Class1::_Age
//ret
setIlgen.Emit(OpCodes.Ldarg_0);
setIlgen.Emit(OpCodes.Ldarg_1);
setIlgen.Emit(OpCodes.Stfld, exField); setIlgen.Emit(OpCodes.Ret);
exProperty.SetSetMethod(exSetMethod);
counter++;
}
finished = myType.CreateType();
You can dynamically set columns with their associated bindings (ensuring that AutoGenerateColumns is off):
For instance, the name column:
DataGridTextColumn txtColumn = new DataGridTextColumn();
textColumn.Header = "Name";
textColumn.Binding = new Binding("FirstName");
myDataGrid.Columns.Add(txttColumn);
The ObservableCollection you use to store the data that is queried could possibly be overriden to support pivoting, making sure to change the binding of the DataGrid columns, as shown above.
Note: This is a fair amount of hand waving i'm sure (haven't touched silverlight for over a year); but I hope it's enough to formulate another strategy.
if you are working with two dimensional array then adding columns dynamically as shown above will not work.
The problem is with silverlight it cannot understand the binding of columns to a list.
So we have to create list of rows with row convertor that will represent our two dimensional arrays.
this one worked for me
http://www.scottlogic.co.uk/blog/colin/2010/03/binding-a-silverlight-3-datagrid-to-dynamic-data-via-idictionary-updated/