Recent

Author Topic: How is best way to mapping objects ?  (Read 1750 times)

Borneq

  • Full Member
  • ***
  • Posts: 248
How is best way to mapping objects ?
« on: December 20, 2019, 08:28:25 pm »
I can use TFPGMap<TKey, TData> but in Pascal objects are not values but pointers.
I have TLabel, instances of can be differ lab1<>lab2 but embed the same fields, lab1.Equaks(lab2). In my example, only TKey is important, TData is idex 0,1,2...
Slow way is simply create List of TLabel, but I can fast found it, this list will unsorted due to often addings, but if is possible hash list mapping not pointer but fields? some hash may be computed by calling my method on TLabel

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: How is best way to mapping objects ?
« Reply #1 on: December 20, 2019, 09:03:45 pm »
One simple way to do this (if I've correctly understood what you need) is to give each label a unique Tag value (all TComponent descendants have a Tag property).

Borneq

  • Full Member
  • ***
  • Posts: 248
Re: How is best way to mapping objects ?
« Reply #2 on: December 21, 2019, 09:43:37 am »
Name TLabel can be misleading. It is not component, but simple object. Problem is finding by vlaue, not by pointer.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5906
  • Compiler Developer
Re: How is best way to mapping objects ?
« Reply #3 on: December 21, 2019, 11:14:21 am »
If you want custom comparisons you might be better of using Generics.Collections.TDictionary<,> with its IEqualityComparer<> interface. Here is an example how you might use it:

Code: Pascal  [Select][+][-]
  1. program tdicttest;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   Generics.Collections, Generics.Defaults, Generics.Hashes;
  7.  
  8. type
  9.   TMyClass = class
  10.     f: LongInt;
  11.   end;
  12.  
  13.   TMyDictionary = specialize TDictionary<TMyClass, LongInt>;
  14.  
  15.   { TMyComparer }
  16.  
  17.   TMyComparer = class(TInterfacedObject, specialize IEqualityComparer<TMyClass>)
  18.     function Equals(constref aLeft, aRight: TMyClass): Boolean;
  19.     function GetHashCode(constref aValue: TMyClass): UInt32;
  20.   end;
  21.  
  22. function TMyComparer.Equals(constref aLeft, aRight: TMyClass): Boolean;
  23. begin
  24.   Result := aLeft.f = aRight.f;
  25. end;
  26.  
  27. function TMyComparer.GetHashCode(constref aValue: TMyClass): UInt32;
  28. begin
  29.   Result := SimpleChecksumHash(@aValue.f, SizeOf(aValue.f));
  30. end;
  31.  
  32. var
  33.   d: TMyDictionary;
  34.   c: TMyClass;
  35. begin
  36.   d := TMyDictionary.Create(TMyComparer.Create);
  37.   c := TMyClass.Create;
  38.   c.f := 42;
  39.   d.Add(c, 0);
  40.   if not d.ContainsKey(c) then
  41.     Writeln('not found (bad)')
  42.   else
  43.     Writeln('found (good)');
  44.   c := TMyClass.Create;
  45.   c.f := 42;
  46.   if not d.ContainsKey(c) then
  47.     Writeln('not found (bad)')
  48.   else
  49.     Writeln('found (good)');
  50.   c.f := 21;
  51.   if not d.ContainsKey(c) then
  52.     Writeln('not found (good)')
  53.   else
  54.     Writeln('found (bad)');
  55. end.

The output is then as follows:

Code: [Select]
PS C:\fpc\git> .\testoutput\tdicttest.exe
found (good)
found (good)
not found (good)

 

TinyPortal © 2005-2018