Forum Delphi.cz

Delphi => Obecné => Téma založeno: František 18-07-2021, 15:17:06

Název: Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 18-07-2021, 15:17:06
Ako správne použiť value TList v TDictionary<string,TList>
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 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

Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 18-07-2021, 18:41:09
este pripajam naplneney TDictionary
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 18-07-2021, 20:06:57
alebo ma nasmerujte na ine riesenie
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: Stanislav Hruška 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:Čiže pracuje s objektmi. Správne máš použiť TStringList.
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 18-07-2021, 23:04:31
no uz mi to nehadze hauznumera a vinimky, ale aj tak TryGet vracia prazdny StringList
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: pf1957 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 :-)
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: pf1957 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
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: Stanislav Hruška 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!
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 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;
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 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?

Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: pf1957 19-07-2021, 11:18:39
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.
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: Stanislav Hruška 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.

Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 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 ...

Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 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.      
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: Stanislav Hruška 20-07-2021, 10:10:39

Ešte jedna vec
Kód: Delphi [Vybrat]
  1.   if sl.Count > 0 then
  2.   begin
  3.     for I := 0 to sl.Count - 1 do
  4.       DictSyno.Add(sl[I], sl);
  5.   end;
Tá podmienka je celkom zbytočná. Pri sl.Count = 0 bude for I := 0 to -1 do. Podmienka pre cyklus nie je nikdy splnená a kód sa nikdy nespustí.
Tiež som to tak robil ;)
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 20-07-2021, 11:22:26
stanislav zabudol si na mtSynon.next; nakonci
Kód: Delphi [Vybrat]
  1.    
  2.     Item := TStringList.create();
  3.     while not mtSynon.Eof do
  4.     begin
  5.       if (group <> Fsyno.AsInteger) or (mtSynon.RecordCount = mtSynon.RecNo) then
  6.       begin
  7.         if mtSynon.RecordCount = mtSynon.RecNo //pridame do SL posledny
  8.             then Item.add(UpperCase(Fslovo.AsString));  
  9.         for i := 0 to Item.Count - 1 do
  10.         begin
  11.             DictSynon.Add(Item[i],Item);          //tu sa naplna Dict, to znamena ze pri poslednom prechode by cyklus while skoncil a nezapisal by do dict
  12.         end;
  13.         Item := TStringList.create();
  14.         group := Fsyno.AsInteger;
  15.       end;
  16.       Item.add(UpperCase(Fslovo.AsString));  //tu sa naplna SL
  17.       mtSynon.next;
  18.     end;
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: Stanislav Hruška 20-07-2021, 11:40:37
Daný kód je až za cyklom while. Takže Next s tým nemá nič spoločné.
Ten vo while som neanalyzoval.
Název: Re:Ako spravne pouzit value TList v TDictionary<string,TList>
Přispěvatel: František 20-07-2021, 11:50:34
ten kod za whiile som vyhodil tou podmienkou, ale ti si naplnal SL stale tou istou hodnotou, chybal ti tam next, lebo tam nema co robit,
cyklus robi to tnaledovne:

next naplna SL
ked pride ku zmene GR tak to zapise do dict a creatne novy SL
ale pri poslednom cykle nedoje uz v starom kode ku zapisu (lebo cyklus konci skor ako dojde ku zmene GR) a preto som to poriesil tou duplicitou, no na tvoj podnet som to upravil tak ako to je teraz