¿Cómo enumero JvMemoryData ... O, cómo creo un hash con una sola clave y múltiples valores?

StackOverflow https://stackoverflow.com/questions/607820

  •  03-07-2019
  •  | 
  •  

Pregunta

Estoy usando JvMemoryData para rellenar un JvDBUltimGrid. Principalmente utilizo este JvMemoryData como una estructura de datos, porque no conozco nada que satisfaga mis necesidades.

No estoy trabajando con muchos datos, pero necesito una forma de enumerar los registros que estoy agregando a JvMemoryData. ¿Alguien ha hecho esto antes? ¿Sería posible de alguna manera " consultar " estos datos usando TSQLQuery?

O, ¿hay una mejor manera de hacer esto? Soy un poco ingenuo cuando se trata de estructuras de datos, por lo que tal vez alguien pueda señalarme en la dirección correcta. Lo que realmente necesito es como un diccionario / hash, que permite 1 clave y muchos valores. Al igual que:

KEY1: val1;val2;val3;val4;val5;etc...
KEY2: val1;val2;val3;val4;val5;etc...

Consideré usar THashedStringList en la unidad IniFiles, pero todavía sufre del mismo problema, ya que solo permite asociar 1 clave a un valor.

¿Fue útil?

Solución

Una forma sería crear una TStringList, y hacer que el objeto de cada elemento apunte a otra TList (o TStringList) que contenga todos sus valores. Si la lista de cadenas superior está ordenada, entonces la recuperación está a solo una búsqueda binaria.

Para agregar elementos a su lista superior, use algo como lo siguiente (SList = TStringList):

Id := SList.AddObject( Key1, tStringList.Create );
InnerList := tStringList(SList.Objects[id]);
// for each child in list
  InnerList.add( value );

Cuando sea el momento de desechar la lista, asegúrate de liberar también cada una de las listas internas.

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);

Otros consejos

No soy un programador de Delphi, pero ¿no podría simplemente usar una lista o matriz como valor para cada entrada hash? En terminología de Java:

Map<String,List>

Parece que ya estás usando Jedi. Jedi contiene clases que te permiten mapear cualquier cosa con cualquier cosa.

Echa un vistazo a esta pregunta relacionada .

He estado usando una matriz de cualquier tipo de registro definido arbitrariamente por el usuario complejo como caché junto con una TStringList o THashedStringList. Accedo a cada registro usando una clave. Primero reviso la lista de cadenas para una coincidencia. Si no coincide, obtengo el registro de la base de datos y lo puse en la matriz. Puse su índice de matriz en la lista de cadenas. Al usar los registros con los que estoy trabajando, así es como se ve mi código:

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;

He estado obteniendo acceso instantáneo de esta manera.

Jack

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top