Jump to content
giomach

Sorting two lists in step?

Recommended Posts

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
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

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

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

@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
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
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

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 by David Heffernan

Share this post


Link to post
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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×