Autor Téma: Ako spravne pouzit value TList v TDictionary<string,TList>  (Přečteno 660 krát)

Offline František

  • Guru
  • *****
  • Příspěvků: 704
  • Karma: 7
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Ako správne použiť value TList v TDictionary<string,TList>

Offline František

  • Guru
  • *****
  • Příspěvků: 704
  • Karma: 7
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #1 kdy: 18-07-2021, 16:11:26 »
v podstate si chcem urobit slovnik synonym (ci skor zamen)
key je slovo
value je zoznam synonym
takze mam v dictionary tolko pozloziek kolko je v zozname vyrazov pre jedno slovo
napr. - je to bez diakritiky
key (value)
biela (biela,bila,bily,biely,white)
bila (biela,bila,bily,biely,white)
bily (biela,bila,bily,biely,white)
biely (biela,bila,bily,biely,white)
white (biela,bila,bily,biely,white)
v DB mam takto
gr, slovo
1 biela
1 bila
1 bily
1 biely
1 white
2 ciena
...
TDictionary<string,TList<string>>;
naplnim v pohode
ale uz to neviem vycitat
kluc mi najde ale value naplni kadecim
Kód: Delphi [Vybrat]
  1.       valx := TList<string>.Create;
  2.       if DictSynon.TryGetValue(keyx, valx)  then
  3.       begin
  4.         j := valx.Count;   //uz tu hadze hauznumera
  5.         for ItemS in valx do   // a tu to pada na AV


Offline František

  • Guru
  • *****
  • Příspěvků: 704
  • Karma: 7
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #2 kdy: 18-07-2021, 18:41:09 »
este pripajam naplneney TDictionary

Offline František

  • Guru
  • *****
  • Příspěvků: 704
  • Karma: 7
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #3 kdy: 18-07-2021, 20:06:57 »
alebo ma nasmerujte na ine riesenie

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6004
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #4 kdy: 18-07-2021, 20:50:04 »
Z nápovede:
TList stores an array of pointers.
TList, which stores an array of pointers, is often used to maintain lists of objects. TList introduces properties and methods to:
  • Add or delete the objects in the list.
  • ...
Čiže pracuje s objektmi. Správne máš použiť TStringList.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline František

  • Guru
  • *****
  • Příspěvků: 704
  • Karma: 7
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #5 kdy: 18-07-2021, 23:04:31 »
no uz mi to nehadze hauznumera a vinimky, ale aj tak TryGet vracia prazdny StringList

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3290
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Ako spravne pouzit value TList v TDictionary<string,TList>
« Odpověď #6 kdy: 19-07-2021, 07:23:38 »
    [/list]Čiže pracuje s objektmi. Správne máš použiť TStringList.
    Ne nutne. To, co si zkopiroval z dox, se vztahuje k TList, kdezto on pracuje s jeho generickou variantou TList<type>.

    Tedy kdyz koukam na ten prispevek znovu, tak uz si tim nejsem jist a buhvi co tam dela... Pokud to nema jako generikum, pak bys mel pravdu :-)
    « Poslední změna: 19-07-2021, 07:27:06 od pf1957 »

    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 3290
    • Karma: 139
      • Verze Delphi: D2007, XE3, DX10
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #7 kdy: 19-07-2021, 07:24:22 »
    no uz mi to nehadze hauznumera a vinimky, ale aj tak TryGet vracia prazdny StringList
    Spis bys mel ukazat cely kod, jak to plnis vcetne deklaraci
    « Poslední změna: 19-07-2021, 07:27:48 od pf1957 »

    Offline Stanislav Hruška

    • Padawan
    • ******
    • Příspěvků: 6004
    • Karma: 44
      • Verze Delphi: W10 + D11
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #8 kdy: 19-07-2021, 08:28:38 »
    Toho generika si som vedomý. Chcel som napísať, aby tu hodil kód ako to napĺňa. Upustil som od toho. Chyba!
    W10 64b, Delphi 10.4, FireBird 3.05
    Expert na kladenie nejasne formulovaných otázok.

    Offline František

    • Guru
    • *****
    • Příspěvků: 704
    • Karma: 7
      • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #9 kdy: 19-07-2021, 08:39:38 »
    Kód: Delphi [Vybrat]
    1. procedure SetDictSynon2(var DictSyno:TDictionary<string,TStringList>);
    2. var
    3.   mtSynon: TFDMemTable;
    4.   Item: TStringList;
    5.   Fgr: TField;
    6.   Fslovo: TField;
    7.   Fgroup: Integer;
    8.   FirstSlovo, ItemS: string;
    9.   i: integer;
    10. begin
    11.   DictSyno.clear;
    12.   Item := TStringList.create();
    13.   try
    14.     mtSynon := Desk.GetMemTableFromSQL('select * from SYNONYM order by gr');
    15.     Fgr := mtSynon.FieldByName('gr');
    16.     Fslovo := mtSynon.FieldByName('slovo');
    17.     Fgroup := Fgr.AsInteger;
    18.     while not mtSynon.Eof do
    19.     begin
    20.       if Fgroup <> Fgr.AsInteger then
    21.       begin
    22.         for i := 0 to Item.Count - 1 do
    23.         begin
    24.             DictSyno.Add(Item[i],Item);
    25.         end;
    26.         Item.clear;
    27.         Fgroup := Fgr.AsInteger;
    28.       end;
    29.       Item.add(UpperCase(Fslovo.AsString));
    30.       mtSynon.next;
    31.     end;
    32.     if item.Count > 0 then
    33.     begin
    34.       for i := 0 to Item.Count - 1 do
    35.       begin
    36.         DictSyno.Add(Item[i],Item);
    37.       end;
    38.     end;
    39.   finally
    40.     item.Free;
    41.   end;
    « Poslední změna: 19-07-2021, 08:50:32 od František »

    Offline František

    • Guru
    • *****
    • Příspěvků: 704
    • Karma: 7
      • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #10 kdy: 19-07-2021, 10:18:25 »
    vdaka za nasmerovanie, uz som na to prisiel
    Kód: Delphi [Vybrat]
    1. procedure SetDictSynon2(var DictSyno:TDictionary<string,TStringList>);
    2. var
    3.   mtSynon: TFDMemTable;
    4.   Item: TStringList;
    5.   Fgr: TField;
    6.   Fslovo: TField;
    7.   Fgroup: Integer;
    8.   FirstSlovo, ItemS: string;
    9.   i: integer;
    10. begin
    11.   DictSyno.clear;
    12.     mtSynon := Desk.GetMemTableFromSQL('select * from SYNONYM order by gr');
    13.     Fgr := mtSynon.FieldByName('gr');
    14.     Fslovo := mtSynon.FieldByName('slovo');
    15.     Fgroup := Fgr.AsInteger;
    16.     Item := TStringList.create();
    17.     while not mtSynon.Eof do
    18.     begin
    19.       if Fgroup <> Fgr.AsInteger then
    20.       begin
    21.         for i := 0 to Item.Count - 1 do
    22.         begin
    23.             DictSyno.Add(Item[i],Item);
    24.         end;
    25.         Item := TStringList.create();
    26.         Fgroup := Fgr.AsInteger;
    27.       end;
    28.       Item.add(UpperCase(Fslovo.AsString));
    29.       mtSynon.next;
    30.     end;
    31.     if item.Count > 0 then
    32.     begin
    33.       for i := 0 to Item.Count - 1 do
    34.       begin
    35.         DictSyno.Add(Item[i],Item);
    36.       end;
    37.     end;
    38.  
    len este jedna podotazka
    objekty item sa uvolnia po uvolneni DictSyno, alebo ich treba predtym uvolnit?


    Offline pf1957

    • Padawan
    • ******
    • Příspěvků: 3290
    • Karma: 139
      • Verze Delphi: D2007, XE3, DX10
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #11 kdy: 19-07-2021, 11:18:39 »
    Excellent
    Rated 1 time
    Kód: Delphi [Vybrat]
    1. procedure SetDictSynon2(var DictSyno:TDictionary<string,TStringList>);
    ...
    Kód: Delphi [Vybrat]
    1. valx := TList<string>.Create;
    2.       if DictSynon.TryGetValue(keyx, valx)  then
    V tomhle mas zmatek: var v prvnim pripade se uvadi jen v pripade, ze chces pres argument DictSyno zmenit hodnotu predane promenne napr. vytvorenim instance TDictionary uvnitr SetDictSynon2, a to ty nechces: ty predas pointer na instanci TDictionary a chces menit obsah toho dictionary. Naopak metoda TryGetValue priradi do promenne valx instanci objektu, ktery existuje jako hodnota v TDictionary, pokud ji najde. Takze kdyz ji pred volanim priradis nove vytvorenou instanci, udelas akorat memory leak, protoze hodnotu nove instance nenavratne ztratis - TryGetValue ji prepise.


    Citace
    objekty item sa uvolnia po uvolneni DictSyno, alebo ich treba predtym uvolnit?
    Misto TDictionary pouzij TObjectDictionary.

    Offline Stanislav Hruška

    • Padawan
    • ******
    • Příspěvků: 6004
    • Karma: 44
      • Verze Delphi: W10 + D11
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #12 kdy: 19-07-2021, 12:43:15 »
    Podľa mňa by to malo byť takto
    Kód: Delphi [Vybrat]
    1. procedure SetDictSynon2(DictSyno:TDictionary<string, TStringList>);
    2. var
    3.   mtSynonym: TFDMemTable;
    4.   sl: TStringList;
    5.   FGroup, FWord: TField;
    6.   I, OldGroup: Integer;
    7. begin
    8.   DictSyno.clear;
    9.   mtSynonym := Desk.GetMemTableFromSQL('SELECT * FROM SYNONYM ORDER BY GR');  //  Zásadne veľké písmená!!!
    10.   FGroup := mtSynonym.FieldByName('GR');
    11.   FWord := mtSynonym.FieldByName('SLOVO');
    12.   OldGroup := FGroup.AsInteger;
    13. .
    14.   while not mtSynonym.Eof do
    15.   begin
    16.     sl := TStringList.create();
    17. .
    18.     if Group <> FGroup.AsInteger then
    19.     begin
    20.       for I := 0 to sl.Count - 1 do
    21.         sl.Add(UpperCase(FWord.AsString));
    22. .
    23.       DictSyno.Add(sl[I], sl);
    24.     end;
    25. .
    26.     OldGroup := FGroup.AsInteger;
    27.     mtSynonym.Next;
    28.   end;
    29. .
    30. //  Prečo to tu zdvojuješ? Máš duplikované údaje !!!
    31.   if sl.Count > 0 then
    32.   begin
    33.     for I := 0 to sl.Count - 1 do
    34.       DictSyno.Add(sl[I], sl);
    35.   end;
    36. end;
    Clear public Clear all data. Podľa mňa to jednoduché štruktúry uvoľní. TStringList je jednoduchá štruktúra.

    W10 64b, Delphi 10.4, FireBird 3.05
    Expert na kladenie nejasne formulovaných otázok.

    Offline František

    • Guru
    • *****
    • Příspěvků: 704
    • Karma: 7
      • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #13 kdy: 19-07-2021, 17:47:03 »
    stanislav, asi si to nepochopil
    najprv si musim nazbierat do StringListu rowy z DB (kym sa nezmeny GR)
    az potom to zapisem do Dictionary
    a duplikovane tam nemam nic iba kod, tak som to dopnil o podmienku
    Kód: Delphi [Vybrat]
    1.  if (group <> Fsyno.AsInteger) or (mtSynon.RecordCount = mtSynon.RecNo) then ...

    « Poslední změna: 19-07-2021, 18:03:23 od František »

    Offline František

    • Guru
    • *****
    • Příspěvků: 704
    • Karma: 7
      • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
    Re:Ako spravne pouzit value TList v TDictionary<string,TList>
    « Odpověď #14 kdy: 19-07-2021, 18:18:33 »
    Misto TDictionary pouzij TObjectDictionary.
    dikez, ako vzdy mi tvoj vyklad pomohol... hlavne ze som ho pochopil
    este vyrez pouzitia slovnika
    Kód: Delphi [Vybrat]
    1.       if DictSynon.TryGetValue(Finding,valx)  then
    2.       begin
    3.         j := valx.Count;
    4.         if j > 0 then
    5.         begin
    6.           result := result + '(';
    7.           for ItemS in valx do
    8.           begin
    9.             result := result + Finding + ' like ' + QuotedStr('%' + ItemS + '%') + ' ';
    10.             dec(j);
    11.             if j > 0 then result := result + 'or ';
    12.           end;
    13.           result := result + ') ';
    14.         end;
    15.       end
    16.       else
    17.       begin
    18.         result := result + Finding + ' like ' + QuotedStr('%' + ss + '%') + ' ';
    19.       end;
    20.