123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- // Generic types for NewPascal.org and FPC!
- // Original version by keeper89.blogspot.com, 2011
- // FPC version by Maciej Izak (hnb), 2014
- program THashMapProject;
- {$MODE DELPHI}
- {$APPTYPE CONSOLE}
- uses
- SysUtils, Generics.Collections, Generics.Defaults;
- type
- TSubscriberInfo = record
- Name, SName: string;
- class function Create(const Name, SName: string): TSubscriberInfo; static;
- function ToString: string;
- end;
- // Class containing handlers add / remove items in the dictionary
- THashMapEventsHandler = class
- public
- class procedure OnKeyNotify(Sender: TObject; constref Item: string;
- Action: TCollectionNotification);
- class procedure OnValueNotify(Sender: TObject; constref Item: TSubscriberInfo;
- Action: TCollectionNotification);
- end;
- class function TSubscriberInfo.Create(const Name,
- SName: string): TSubscriberInfo;
- begin
- Result.Name := Name;
- Result.SName := SName;
- end;
- function TSubscriberInfo.ToString: string;
- begin
- Result := Format('%s %s', [Name, SName]);
- end;
- // Function to generate the dictionary contents into a string
- function PrintTelephoneDirectory(
- TelephoneDirectory: THashMap<string, TSubscriberInfo>): string;
- var
- PhoneNumber: string;
- begin
- Result := Format('Content directory (%d):', [TelephoneDirectory.Count]);
- for PhoneNumber in TelephoneDirectory.Keys do
- Result := Result + Format(LineEnding + '%s: %s',
- [PhoneNumber, TelephoneDirectory[PhoneNumber].ToString]);
- end;
- // Handlers add / remove items dictionary
- class procedure THashMapEventsHandler.OnKeyNotify(Sender: TObject;
- constref Item: string; Action: TCollectionNotification);
- begin
- case Action of
- cnAdded:
- Writeln(Format('OnKeyNotify! Phone %s added!', [Item]));
- cnRemoved:
- Writeln(Format('OnKeyNotify! Number %s deleted!', [Item]));
- end;
- end;
- class procedure THashMapEventsHandler.OnValueNotify(Sender: TObject;
- constref Item: TSubscriberInfo; Action: TCollectionNotification);
- begin
- case Action of
- cnAdded:
- Writeln(Format('OnValueNotify! Subscriber %s added!', [Item.ToString]));
- cnRemoved:
- Writeln(Format('OnValueNotify! Subscriber %s deleted!', [Item.ToString]));
- end;
- end;
- function CustomCompare(constref Left, Right: TPair<string, TSubscriberInfo>): Integer;
- begin
- // Comparable full first names, and then phones if necessary
- Result := TCompare.&String(Left.Value.ToString, Right.Value.ToString);
- if Result = 0 then
- Result := TCompare.&String(Left.Key, Right.Key);
- end;
- var
- // Declare the "dictionary"
- // key is the telephone number which will be possible
- // to determine information about the owner
- TelephoneDirectory: THashMap<string, TSubscriberInfo>;
- TTelephoneArray: array of TPair<string, TSubscriberInfo>;
- TTelephoneArrayItem: TPair<string, TSubscriberInfo>;
- PhoneNumber: string;
- Subscriber: TSubscriberInfo;
- begin
- WriteLn('Working with THashMap - phonebook');
- WriteLn;
- // create a directory
- // Constructor has several overloaded options which will
- // enable the capacity of the container, a comparator for values
- // or the initial data - we use the easiest option
- TelephoneDirectory := THashMap<string, TSubscriberInfo>.Create;
- // ---------------------------------------------------
- // 1) Adding items to dictionary
- // Add new users to the phonebook
- TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Arnold', 'Schwarzenegger'));
- TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Jessica', 'Alba'));
- TelephoneDirectory.Add('9203333333', TSubscriberInfo.Create('Brad', 'Pitt'));
- TelephoneDirectory.Add('9204444444', TSubscriberInfo.Create('Brad', 'Pitt'));
- TelephoneDirectory.Add('9205555555', TSubscriberInfo.Create('Sandra', 'Bullock'));
- // Adding a new subscriber if number already exist
- TelephoneDirectory.AddOrSetValue('9204444444',
- TSubscriberInfo.Create('Angelina', 'Jolie'));
- // Print list
- Writeln(PrintTelephoneDirectory(TelephoneDirectory));
- // ---------------------------------------------------
- // 2) Working with the elements
- // Set the "capacity" of the dictionary according to the current number of elements
- TelephoneDirectory.TrimExcess;
- // Is there a key? - ContainsKey
- if TelephoneDirectory.ContainsKey('9205555555') then
- Writeln('Phone 9205555555 registered!');
- // Is there a subscriber? - ContainsValue
- Subscriber := TSubscriberInfo.Create('Sandra', 'Bullock');
- if TelephoneDirectory.ContainsValue(Subscriber) then
- Writeln(Format('%s is in the directory!', [Subscriber.ToString]));
- // Try to get information via telephone. TryGetValue
- if TelephoneDirectory.TryGetValue('9204444444', Subscriber) then
- Writeln(Format('Number 9204444444 belongs to %s', [Subscriber.ToString]));
- // Directly access by phone number
- Writeln(Format('Phone 9201111111 subscribers: %s', [TelephoneDirectory['9201111111'].ToString]));
- // Number of people in the directory
- Writeln(Format('Total subscribers in the directory: %d', [TelephoneDirectory.Count]));
- // ---------------------------------------------------
- // 3) Delete items
- // Schwarzenegger now will not be listed
- TelephoneDirectory.Remove('9201111111');
- // Completely clear the list
- TelephoneDirectory.Clear;
- // ---------------------------------------------------
- // 4) Events add / remove values
- //
- // Events OnKeyNotify OnValueNotify are designed for "tracking"
- // for adding / removing keys and values respectively
- TelephoneDirectory.OnKeyNotify := THashMapEventsHandler.OnKeyNotify;
- TelephoneDirectory.OnValueNotify := THashMapEventsHandler.OnValueNotify;
- Writeln;
- // Try events
- TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Arnold', 'Schwarzenegger'));
- TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Jessica', 'Alba'));
- TelephoneDirectory['9202222222'] := TSubscriberInfo.Create('Monica', 'Bellucci');
- TelephoneDirectory.Clear;
- WriteLn;
- TelephoneDirectory.Add('9201111111', TSubscriberInfo.Create('Monica', 'Bellucci'));
- TelephoneDirectory.Add('9202222222', TSubscriberInfo.Create('Sylvester', 'Stallone'));
- TelephoneDirectory.Add('9203333333', TSubscriberInfo.Create('Bruce', 'Willis'));
- WriteLn;
- // Show keys (phones)
- Writeln('Keys (phones):');
- for PhoneNumber in TelephoneDirectory.Keys do
- Writeln(PhoneNumber);
- Writeln;
- // Show values (subscribers)
- Writeln('Values (subscribers):');
- for Subscriber in TelephoneDirectory.Values do
- Writeln(Subscriber.ToString);
- Writeln;
- // All together now
- Writeln('Subscribers list with phones:');
- for PhoneNumber in TelephoneDirectory.Keys do
- Writeln(Format('%s: %s',
- [PhoneNumber, TelephoneDirectory[PhoneNumber].ToString]));
- Writeln;
- // In addition, we can "export" from the dictionary
- // to TArray
- // Sort the resulting array and display
- TTelephoneArray := TelephoneDirectory.ToArray;
- // partial specializations not allowed
- // same for anonymous methods
- //TArray.Sort<TPair<string, TSubscriberInfo>>(
- // TTelephoneArray, TComparer<TPair<string, TSubscriberInfo>>.Construct(
- // function (const Left, Right: TPair<string, TSubscriberInfo>): Integer
- // begin
- // // Comparable full first names, and then phones if necessary
- // Result := CompareStr(Left.Value.ToString, Right.Value.ToString);
- // if Result = 0 then
- // Result := CompareStr(Left.Key, Right.Key);
- // end));
- TArrayHelper<TelephoneDirectory.TDictionaryPair>.Sort(
- TTelephoneArray, TComparer<TelephoneDirectory.TDictionaryPair>.Construct(
- CustomCompare));
- // Print
- Writeln('Sorted list of subscribers into TArray (by name, and eventually by phone):');
- for TTelephoneArrayItem in TTelephoneArray do
- Writeln(Format('%s: %s',
- [TTelephoneArrayItem.Value.ToString, TTelephoneArrayItem.Key]));
- Writeln;
- FreeAndNil(TelephoneDirectory);
- Readln;
- end.
|