OZ8HP
OZ8HP

Reputation: 1513

Why doesn't my TStringList gets sorted

I Have a TStringList I create on FormCreate

  ScriptList := TStringList.Create;

In another function in my program after I have loaded strings into the list I have the following code

  ScriptList.Sorted := True;
  ScriptList.Sort;
  for i := 0 to ScriptList.Count - 1 do
    ShowMessage(ScriptList[i]);

But the list is not sorted Why is that?

Edited: Filling the list is done by the following code

function TfrmMain.ScriptsLocate(const aComputer: boolean = False): integer;
var
  ScriptPath: string;
  TempList: TStringList;
begin
  TempList := TStringList.Create;
  try
    if aComputer = True then
      begin
        ScriptPath := Folders.DirScripts;
        Files.Search(TempList, ScriptPath, '*.logon', False);
        ScriptList.AddStrings(TempList);
      end
    else
      begin
        if ServerCheck then
          begin
            ScriptPath := ServerPath + 'scripts_' + Network.ComputerName + '\';
            Folders.Validate(ScriptPath);
            TempList.Clear;
            Files.Search(TempList, ScriptPath, '*.logon', False);
            ScriptList.AddStrings(TempList);
            Application.ProcessMessages;

            ScriptPath := ServerPath + 'scripts_' + 'SHARED\';
            Folders.Validate(ScriptPath);
            TempList.Clear;
            Files.Search(TempList, ScriptPath, '*.logon', False);
            ScriptList.AddStrings(TempList);
          end;
      end;
  finally
    TempList.Free;
  end;
  ScriptList.Sort;
  Result := ScriptList.Count;
end;

The filesearch function:

function TFiles.Search(aList: TstringList; aPathname: string; const aFile: string = '*.*'; const aSubdirs: boolean = True): integer;
var
  Rec: TSearchRec;
begin
  Folders.Validate(aPathName, False);
  if FindFirst(aPathname + aFile, faAnyFile - faDirectory, Rec) = 0 then
    try
      repeat
        aList.Add(aPathname + Rec.Name);
      until FindNext(Rec) <> 0;
    finally
      FindClose(Rec);
    end;
  Result := aList.Count;
  if not aSubdirs then Exit;
  if FindFirst(aPathname + '*.*', faDirectory, Rec) = 0 then
    try
      repeat
        if ((Rec.Attr and faDirectory) <> 0)  and (Rec.Name<>'.') and (Rec.Name<>'..') then
          Files.Search(aList, aPathname + Rec.Name, aFile, True);
        until FindNext(Rec) <> 0;
    finally
      FindClose(Rec);
    end;
  Result := aList.Count;
end;

The main problem is that the list is filled OK with the items I want, but it never gets sorted.

Upvotes: 1

Views: 403

Answers (1)

David Heffernan
David Heffernan

Reputation: 612964

When you set Sorted to True you are saying that you want the list to be maintained in order. When new items are added, they will be inserted in order. When Sorted is True, the Sort method does nothing because the code is built on the assumption that the list is already order.

So, in your code calling Sort does nothing and could be removed. However, I would take the alternative approach, remove the setting of Sorted and call Sort explicitly:

ScriptList.LoadFromFile(...);
ScriptList.Sort;
for i := 0 to ScriptList.Count - 1 do
  ...

Now, in fact I think that your code is not quite as you have claimed. You claim that you load the file, and then set Sorted to True. That cannot be the case. Here is the SetSorted implementation:

procedure TStringList.SetSorted(Value: Boolean);
begin
  if FSorted <> Value then
  begin
    if Value then Sort;
    FSorted := Value;
  end;
end;

So, if Sorted is False when you set it to True, the list will be sorted.


But even that does not explain what you report. Because if Sorted is True when you call LoadFromFile, each new line will be inserted in order. So, what you report in the question cannot be the whole story.


Unless you are making subsequent additions to the list, it is cleaner, in my view, to ignore the Sorted property. Leave Sorted as its default value of False. And call Sort when you want to enforce an ordering to the list. All the same, it might be worth digging a bit deeper to understand why your assertions in the question don't tally with the implementation of TStringList.

Upvotes: 8

Related Questions