Как мне перечислить JvMemoryData… Или как создать хеш с одним ключом и несколькими значениями?
-
03-07-2019 - |
Вопрос
Я использую JvMemoryData для заполнения JvDBultimGrid.В основном я использую JvMemoryData в качестве структуры данных, поскольку мне не известно ничего другого, что отвечало бы моим потребностям.
Я не работаю с большим количеством данных, но мне нужен способ перечислить записи, которые я добавляю в JvMemoryData.Кто-нибудь делал это раньше?Можно ли как-то «запросить» эти данные с помощью TSQLQuery?
Или есть лучший способ сделать это?Я немного наивен, когда дело касается структур данных, поэтому, возможно, кто-нибудь сможет указать мне правильное направление.Что мне действительно нужно, так это словарь/хеш, который допускает один ключ и множество значений.Вот так:
KEY1: val1;val2;val3;val4;val5;etc...
KEY2: val1;val2;val3;val4;val5;etc...
Я рассматривал возможность использования THashedStringList в модуле IniFiles, но он по-прежнему страдает от той же проблемы, поскольку позволяет связать со значением только один ключ.
Решение
Одним из способов было бы создать TStringList и указать объект каждого элемента на другой TList (или TStringList), который будет содержать все ваши значения.Если самый верхний список строк отсортирован, то поиск осуществляется с помощью двоичного поиска.
Чтобы добавить элементы в самый верхний список, используйте что-то вроде следующего (SList = TStringList):
Id := SList.AddObject( Key1, tStringList.Create );
InnerList := tStringList(SList.Objects[id]);
// for each child in list
InnerList.add( value );
Когда придет время удалить список, убедитесь, что вы также освободили каждый из внутренних списков.
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);
Другие советы
Я не программист Delphi, но не могли бы вы просто использовать список или массив в качестве значения для каждой записи хеша?В терминологии Java:
Map<String,List>
Кажется, ты уже используешь Джедаев.В Jedi есть классы, которые позволяют сопоставлять что угодно с чем угодно.
Взгляни на это связанный вопрос.
Я использовал массив любых произвольно сложных типов записей, определяемых пользователем, в качестве кеша в сочетании с TStringList или THashedStringList.Я получаю доступ к каждой записи с помощью ключа.Сначала я проверяю список строк на предмет совпадения.Если совпадений нет, я получаю запись из базы данных и помещаю ее в массив.Я поместил индекс его массива в список строк.Используя записи, с которыми я работаю, мой код выглядит следующим образом:
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;
Таким образом я получаю, казалось бы, мгновенный доступ.
Джек