Board index » delphi » TStringList.Sort No case sensitive sorting?

TStringList.Sort No case sensitive sorting?

Hi all,

I'm using D4/D5 and want the TStringList sorting to be case sensitive, can
anyone tell me how to get it so sort this way without editing the VCL source
code?

 

Re:TStringList.Sort No case sensitive sorting?


Quote
> I'm using D4/D5 and want the TStringList sorting to be case sensitive

Thanks so much for saying which version. Most people omit this, and it is
frequently important, as in this case where the solution between versions is
totally different.

In D4, there is no easy way to do this -- it was a hard-coded assumption in
the VCL. However, I've written a utility function for you which you can use
to sort a D4 TStringList with or without case sensititivity, and you should
be able to use the same technique to sort a TStringList using any arbitrary
criteria.

D5 actually fixes this oversight, see below for a much easier way to
implement this in D5.

{ D4 code - tested }

type
  TStringItem = class
    Text: String;
    Obj: TObject;
    constructor Create(const AText: string; AObj: TObject);
  end;

constructor TStringItem.Create(const AText: string; AObj: TObject);
begin
  inherited Create;
  Text := AText;
  Obj := AObj;
end;

function SortItemsWithCase(Item1, Item2: Pointer): Integer;
begin
  Result := AnsiCompareStr(TStringItem(Item1).Text,
TStringItem(Item2).Text);
end;

function SortItemsWithoutCase(Item1, Item2: Pointer): Integer;
begin
  Result := AnsiCompareText(TStringItem(Item1).Text,
TStringItem(Item2).Text);
end;

procedure SortStrings(Strings: TStrings; CaseSensitive: Boolean);
var
  List: TList;
  I: Integer;
  Item: TStringItem;
begin
  List := TList.Create;
  try
    { Copy Strings to List }
    for I := 0 to Strings.Count - 1 do
      List.Add(TStringItem.Create(Strings[I], Strings.Objects[I]));
    { Sort List }
    if CaseSensitive
      then List.Sort(SortItemsWithCase)
      else List.Sort(SortItemsWithoutCase);
    { Copy sorted List to Strings }
    Strings.BeginUpdate;
    try
      Strings.Clear;
      for I := 0 to List.Count - 1 do
      begin
        Item := TStringItem(List[I]);
        Strings.AddObject(Item.Text, Item.Obj)
      end;
    finally
      Strings.EndUpdate;
    end;
  finally
    List.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SortStrings(ListBox1.Items, False);
end;

{ D5 code }

function SortWithoutCase(List: TStringList; Index1, Index2: Integer):
Integer;
begin
  Result := AnsiCompareStr(List[Index1], List[Index2]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Strings: TStringList;
begin
  Strings := TStringList.Create;
  try
    { Items is TStrings, not TStringList }
    Strings.Assign(ListBox1.Items);
    { CustomSort is a method of TStringList, not TStrings }
    Strings.CustomSort(SortWithoutCase);
    ListBox1.Items.Assign(Strings);
  finally
    Strings.Free;
  end;
end;

- Rick

Other Threads