-1

I have a little problem with sorting TStringList with mixed values. Its something like:

7567533575 Joe
1543779744 Ann
9757462323 Jack
6999966578 Stef

and I need to sort this list to see:

1543779744 Ann
6999966578 Stef
7567533575 Joe
9757462323 Jack

I can do this with about 3x for loops, with string trim and one array. But it is very lame solution... I guess, someone have best code for this. I dont understand CustomSort... ehh. Please, help me.

  • I use Delphi 10.
LU RD
  • 34,438
  • 5
  • 88
  • 296
DD Charlie
  • 15
  • 1
  • 3
    That looks like a pretty forward, simple string sorting to me. What am I missing here? – Uwe Raabe Dec 18 '17 at 16:31
  • What exactly are you having problems with? What have you tried and why did it not work as you wished? – Tom Brunberg Dec 18 '17 at 16:42
  • 1
    What happens when you have two rows with the same number but different names? You have not actually defined an order yet? – David Heffernan Dec 18 '17 at 16:54
  • Are all of the numbers exactly 10 digits? – lurker Dec 18 '17 at 17:36
  • Yeap, as you see – DD Charlie Dec 18 '17 at 17:39
  • Which is first : `1543779744 Ann` or `1543779744 Anna`? – LU RD Dec 18 '17 at 17:45
  • Your problem is hopelessly underspecified, so I don't know whether this will help you. However, in general one would want to use [natural sort](https://en.wikipedia.org/wiki/Natural_sort_order) for sorting "mixed values", and a Google search for "delphi natural sort" gives you [an old Delphi question here on SO](https://stackoverflow.com/questions/5134712/how-to-get-the-sort-order-in-delphi-as-in-windows-explorer) as the first result. – mghie Dec 18 '17 at 20:11

1 Answers1

5

Using CustomSort() is the correct solution. Simply pass it a function that parses and compares 2 input strings, returning:

  • < 0 if the 1st string should appear before the 2nd string.

  • 0 if the 2 strings are "equal" and either string can appear before the other.

  • > 0 if the 2nd string should appear before the 1st string.

function MySortFunc(List: TStringList; Index1, Index2: Integer): Integer;
var
  Value1, Value2: Int64;
  S: string;
begin
  S := List[Index1];
  Value1 := StrToInt64(Copy(S, 1, Pos(' ', S)-1));
  S := List[Index2];
  Value2 := StrToInt64(Copy(S, 1, Pos(' ', S)-1));
  if Value1 < Value2 then
    Result := -1
  else if Value2 < Value1 then
    Result := 1
  else
    Result := 0;
end;

MyStringList.CustomSort(MySortFunc);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770