Подтвердить что ты не робот

Delphi hashmap?

У меня есть java-код, заполняющий хэш файл из текстового файла.
 HashMap<String, String[]> data = new HashMap<String, String[]>();

Я использую это для создания пар ключ-значение. значения представляют собой массив строк. я должен перебирать все возможные комбинации пар ключ-значение (так что также нужно перебирать массив String []). Это работает с java, но теперь мне нужно передать это в delphi. можно ли это сделать? и как? благодарю!

4b9b3361

Ответ 1

В Delphi 2009 и выше вы можете использовать TDictionary<string, TStringlist> с помощью Generics.Collections.

В более старых версиях вы можете использовать TStringlist, где каждый элемент в TStringlist имеет связанное с ним значение типа TStrings.

У Docwiki есть страница начать с TDictionary

Ответ 2

Если у вас установлена ​​более старая версия Delphi (Delphi 6 и выше), вы также можете использовать динамический массив записей, а затем наши обертки TDynArray или TDynArrayHashed для создания словаря с одним полем записей динамического массива, См. этот блок.

Обертка TDynArrayHashed была разработана как быстрая.

Вот пример кода (из прилагаемых унитарных тестов):

var ACities: TDynArrayHashed;
    Cities: TCityDynArray;
    CitiesCount: integer;
    City: TCity;
    added: boolean;
    N: string;
    i,j: integer;
const CITIES_MAX=200000;
begin
  // valide generic-like features
  // see http://docwiki.embarcadero.com/CodeExamples/en/Generics_Collections_TDictionary_(Delphi)
  ACities.Init(TypeInfo(TCityDynArray),Cities,nil,nil,nil,@CitiesCount);
  (...)
  Check(ACities.FindHashed(City)>=0);
  for i := 1 to 2000 do begin
    City.Name := IntToStr(i);
    City.Latitude := i*3.14;
    City.Longitude := i*6.13;
    Check(ACities.FindHashedAndUpdate(City,true)=i+2,'multiple ReHash');
    Check(ACities.FindHashed(City)=i+2);
  end;
  ACities.Capacity := CITIES_MAX+3; // make it as fast as possible
  for i := 2001 to CITIES_MAX do begin
    City.Name := IntToStr(i);
    City.Latitude := i*3.14;
    City.Longitude := i*6.13;
    Check(ACities.FindHashedAndUpdate(City,true)=i+2,'use Capacity: no ReHash');
    Check(ACities.FindHashed(City.Name)=i+2);
  end;
  for i := 1 to CITIES_MAX do begin
    N := IntToStr(i);
    j := ACities.FindHashed(N);
    Check(j=i+2,'hashing with string not City.Name');
    Check(Cities[j].Name=N);
    CheckSame(Cities[j].Latitude,i*3.14);
    CheckSame(Cities[j].Longitude,i*6.13);
  end;
end;

Итак, для вашей проблемы:

type
  TMyMap = record
    Key: string;
    Value: array of string;
  end;
  TMyMapDynArray = array of TMyMap;

var
  Map: TMyMap;
  Maps: TMyMapDynArray;
  MapW: TDynArrayHashed;
  key: string;
  i: integer;
begin
  MapW.Init(TypeInfo(TMyMapDynArray),Maps);
  Map.Key := 'Some key';
  SetLength(Map.Value,2);
  Map.Value[0] := 'One';
  Map.Value[1] := 'Two';
  MapW.FindHashedAndUpdate(Map,true); // ,true for adding the Map content
  key := 'Some key';
  i := MapW.FindHashed(key);
  // now i=0 and Maps[i].Key=key
  for i := 0 to MapW.Count-1 do // or  for i := 0 to high(Maps) do
    with Maps[i] do
    // now you're enumerating all key/value pairs
end;

Ответ 3

Так как Delphi 6, набор предопределенных классов контейнеров включает TBucketList и TObjectBucketList. Эти два списка являются ассоциативными, что означает, что у них есть ключ и фактическая запись. Ключ используется для идентификации элементов и поиска их. Чтобы добавить элемент, вы вызываете метод Add с двумя параметрами: ключом и данными. Когда вы используете метод Find, вы передаете ключ и извлекаете данные. Тот же эффект достигается с помощью свойства Data array, передающего ключ как параметр.