开发者

delphi hashmap?

i have java-code filling a hashmap from a textfile.

HashMap<String, String[]> data = new HashMap<String, String[]>();

i use this to make key-value-pairs. the values are an array of string. i have to iterate over every possible combo of the key-value-pairs (so also have to iterate over the String[]-array). This works with java but now i have to port this to delphi. is it possible to do so开发者_Go百科? and how? thanks!


In Delphi 2009 and higher, you can use TDictionary<string, TStringlist> using Generics.Collections.

In older versions, you can use TStringlist where every item in the TStringlist has an associated object value of type TStrings.

The Docwiki has a page to get started with TDictionary


If you have an older version of Delphi (Delphi 6 and up), you could also use a dynamic array of record, then our TDynArray or TDynArrayHashed wrappers to create a dictionary with one field of the dynamic array records. See this unit.

The TDynArrayHashed wrapper was developed to be fast.

Here is some sample code (from supplied unitary tests):

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;

So for your problem:

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;


Since Delphi 6, the set of predefined container classes includes TBucketList and TObjectBucketList. These two lists are associative, which means they have a key and an actual entry. The key is used to identify the items and search for them. To add an item, you call the Add method with two parameters: the key and the data. When you use the Find method, you pass the key and retrieve the data. The same effect is achieved by using the Data array property, passing the key as parameter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜