I am using JvMemoryData to populate a JvDBUltimGrid. I'm primarily using this JvMemoryData as a data structure, because I am not aware of anything else that meets my needs.
I'm not working with a lot of data, but I do need a way to enumerate the records I am adding to JvMemoryData. Has anyone done this before? Would it be possible to somehow "query" this data using TSQLQuery?
Or, is there a better way to do this? I'm a bit naive when it comes to data structures, so maybe someone can point me in the right direction. What I really need is like a Dictionary/Hash, that allows for 1 key, and many values. Like so:
KEY1: val1;val2;val3;val4;val5;etc...
KEY2: val1;val2;val3;val4;val5;etc...
I considered using THashedStringList in the IniFiles unit, but it still suffers from the same problem in that it allows only 1 key to be associated with a value.
-
I'm not a Delphi programmer but couldn't you just use a list or array as the value for each hash entry? In Java terminology:
Map<String,List>
Mick : I'll look into that. That sounds like exactly what I want.Mason Wheeler : Yeah, if you've got D2009, you can do this as a TDictionary or TObjectDictionary. -
I have been using an array of any arbitrarily complex user defined record types as a cache in conjunction with a TStringList or THashedStringList. I access each record using a key. First I check the string list for a match. If no match, then I get the record from the database and put it in the array. I put its array index into the string list. Using the records I am working with, this is what my code looks like:
function TEmployeeCache.Read(sCode: String): TEmployeeData; var iRecNo: Integer; oEmployee: TEmployee; begin iRecNo := CInt(CodeList.Values[sCode]); if iRecNo = 0 then begin iRecNo := FNextRec; inc(FNextRec); if FNextRec > High(Cache) then SetLength(Cache, FNextRec * 2); oEmployee := TEmployee.Create; oEmployee.Read(sCode); Cache[iRecNo] := oEmployee.Data; oEmployee.Free; KeyList.Add(Format('%s=%s', [CStr(Cache[iRecNo].hKey), IntToStr(iRecNo)])); CodeList.Add(Format('%s=%s', [sCode, IntToStr(iRecNo)])); end; Result := Cache[iRecNo]; end;
I have been getting seemingly instant access this way.
Jack
-
You already seem to be using Jedi. Jedi contains classes that allow you to map anything with anything.
Take a look at this related question.
Mick : I hadn't seen that, very nice. -
One way would be to create a TStringList, and have each item's object point to another TList (or TStringList) which would contain all of your values. If the topmost string list is sorted, then retrieval is just a binary search away.
To add items to your topmost list, use something like the following (SList = TStringList):
Id := SList.AddObject( Key1, tStringList.Create ); InnerList := tStringList(SList.Objects[id]); // for each child in list InnerList.add( value );
When its time to dispose the list, make sure you free each of the inner lists also.
for i := 0 to SList.count-1 do begin if Assigned(SList.Objects[i]) then SList.Objects[i].free; SList.Objects[i] := nil; end; FreeAndNil(SList);
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.