Como posso enumerar JvMemoryData ... Ou, como faço para criar um hash com uma chave única e vários valores?
-
03-07-2019 - |
Pergunta
Eu estou usando JvMemoryData para preencher um JvDBUltimGrid. Eu estou usando principalmente este JvMemoryData como uma estrutura de dados, porque eu não tenho conhecimento de qualquer outra coisa que atenda às minhas necessidades.
Eu não estou trabalhando com um monte de dados, mas eu preciso de uma maneira para enumerar os registros que estou adicionando a JvMemoryData. Alguém já fez isso antes? Seria possível alguma forma "consulta" esses dados usando TSQLQuery?
Ou, se existe uma maneira melhor de fazer isso? Eu sou um pouco ingênuo quando se trata de estruturas de dados, então talvez alguém pode me apontar na direção certa. O que eu realmente preciso é como um dicionário / Hash, que permite uma chave, e muitos valores. Como assim:
KEY1: val1;val2;val3;val4;val5;etc...
KEY2: val1;val2;val3;val4;val5;etc...
Eu considerei usando THashedStringList na unidade IniFiles, mas ainda sofre do mesmo problema na medida em que permite que apenas 1 chave para ser associado com um valor.
Solução
Uma forma seria a de criar um TStringList e tem ponto de objeto de cada item para outro TList (ou TStringList) que conteria todos os seus valores. Se a lista de corda superior é ordenada, então a recuperação é apenas uma busca binária de distância.
Para adicionar itens à sua lista de nível superior, use algo como o seguinte (SList = TStringList):
Id := SList.AddObject( Key1, tStringList.Create );
InnerList := tStringList(SList.Objects[id]);
// for each child in list
InnerList.add( value );
Quando é hora de eliminar a lista, certifique-se de libertar cada uma das listas internas também.
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);
Outras dicas
Eu não sou um programador Delphi, mas você não pode apenas usar uma lista ou matriz como o valor para cada entrada de hash? Na terminologia Java:
Map<String,List>
Eu tenho usado uma variedade de quaisquer tipos arbitrariamente complexas recordes definidos pelo usuário como um cache em conjunto com um TStringList ou THashedStringList. Eu acessar cada registro usando uma chave. Primeiro eu verificar a lista de string para uma partida. Se nenhuma correspondência, então eu obter o registro do banco de dados e colocá-lo na matriz. Eu coloquei seu índice da matriz na lista de string. Usando os registros que eu estou trabalhando com, isso é o que minha aparência código como:
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;
eu fui ficando acesso aparentemente instantânea desta forma.
Jack