Fr0sT.Brutal 900 Posted May 12, 2023 12 hours ago, giomach said: My version of Delphi (XE) doesn't seem to have this It was since the very beginning I suppose. But it was intended for key-value data like ini files but served also as a kind of surrogate of a dictionary until it was introduced. Share this post Link to post
David Heffernan 2345 Posted May 12, 2023 12 hours ago, giomach said: 3. Use a TPair in TList This is promising because (in contrast to no 1) both TList.Sort and TList.BinarySearch seem to support a custom comparison (in which I would use only the first element of the pair). It is next on my list. Is you real problem that these two strings belong together? In which case declare a record with them in, store them in TList<TYourRecord> and that's the answer, end of story. Share this post Link to post
Minox 7 Posted May 12, 2023 Handle it like a data store? In the sense of creating a record for the first file where some fields point to the second file, so when you order the first, to read in the second file you just need to read the pointer. Share this post Link to post
giomach 1 Posted May 14, 2023 TDictionary has now solved the problem — but not exactly in the way I expected. To summarize, I have two programs — a "setup" program which produces data in the form of two stringlists which correspond item-by-item; and a "user" program which reads this data and repeatedly looks up a string in the first list and extracts the corresponding string from the second list. This works perfectly well, but in raising this thread I sought to improve the speed of TStringList.IndexOf in the user program by sorting the first list in the setup program before exporting it. To do this, while keeping the two lists aligned, I combined them into a single "name=value" stringlist, which I custom-sorted on the "name" and exported to the user program. But in the user program, searching the combined stringlist, IndexOfName still used the slow linear search. Next, in the user program, it would have been logical to re-separate the combined list into two stringlists, but instead I chose to skip that avenue, and to read the combined list into TDictionary. Access from there works and is very fast. I had considered using TDictionary in the setup program, but it has no SaveToFile member. In fact, a TStringList seems to be one of the few things that can be passed from one program to another via a file. So the TDictionary processing has to take place in the user program, and there is no point in having the data sorted in the setup program. That is, I had to add processing into the user program in order to speed it up! Thank you all for your contributions to the solution, including those whose suggestions I did not get around to trying. Share this post Link to post
programmerdelphi2k 237 Posted May 15, 2023 @giomach saving your dic in a file var MyDict: TDictionary<Integer, String>; MyValues: TStringList; begin MyDict := TDictionary<String, String>.Create; MyValues := TStringList.Create; try // add your values on dic MyDict.Add('xxxx', 'yyyy'); // store your dic values in your stringlist temp to save it for var Pair in MyDict do MyValues.Add(Format('%d=%s', [Pair.Key, Pair.Value])); // save it using StringList MyValues.SaveToFile('yourFile.txt'); finally MyDict.Free; MyValues.Free; end; end; Share this post Link to post
David Heffernan 2345 Posted May 15, 2023 5 hours ago, giomach said: TDictionary has now solved the problem — but not exactly in the way I expected. To summarize, I have two programs — a "setup" program which produces data in the form of two stringlists which correspond item-by-item; and a "user" program which reads this data and repeatedly looks up a string in the first list and extracts the corresponding string from the second list. This works perfectly well, but in raising this thread I sought to improve the speed of TStringList.IndexOf in the user program by sorting the first list in the setup program before exporting it. To do this, while keeping the two lists aligned, I combined them into a single "name=value" stringlist, which I custom-sorted on the "name" and exported to the user program. But in the user program, searching the combined stringlist, IndexOfName still used the slow linear search. Next, in the user program, it would have been logical to re-separate the combined list into two stringlists, but instead I chose to skip that avenue, and to read the combined list into TDictionary. Access from there works and is very fast. I had considered using TDictionary in the setup program, but it has no SaveToFile member. In fact, a TStringList seems to be one of the few things that can be passed from one program to another via a file. So the TDictionary processing has to take place in the user program, and there is no point in having the data sorted in the setup program. That is, I had to add processing into the user program in order to speed it up! Thank you all for your contributions to the solution, including those whose suggestions I did not get around to trying. Fairly simple to write a function to save the content of a collection to a text file. Share this post Link to post
Uwe Raabe 2057 Posted May 15, 2023 Even StackOverflow has solutions for that: TDictionary save to file Delphi Dictionary Save/Load. TDictionary not serializable? Share this post Link to post
Fr0sT.Brutal 900 Posted May 15, 2023 6 hours ago, programmerdelphi2k said: MyValues.Add(Format('%d=%s', [Pair.Key, Pair.Value])); Note that neither key nor value must not contain separator char Share this post Link to post
David Heffernan 2345 Posted May 15, 2023 (edited) The most interesting thing here for me is that the question asks about sorting, but in reality what you wanted to do was efficient lookup of name/value pairs. Edited May 15, 2023 by David Heffernan Share this post Link to post
ioan 45 Posted May 15, 2023 On 5/10/2023 at 1:39 PM, Uwe Raabe said: I'm glad that nobody suggested a solution involving an SQL server, yet. TClientDataSet 😉 Share this post Link to post