Delphi HashMap? - PullRequest
       33

Delphi HashMap?

14 голосов
/ 04 апреля 2011

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

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

Ответы [ 3 ]

17 голосов
/ 04 апреля 2011

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

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

В Docwiki есть страница для начала работы с TDictionary

3 голосов
/ 30 декабря 2014

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

3 голосов
/ 04 апреля 2011

Если у вас более старая версия Delphi (Delphi 6 и выше), вы также можете использовать динамический массив из record , тогда наши 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...