Reputation: 3015
I have a TStringList
that have quite many lines of strings.
What I want to do now is to sort this TStringList
on certain values depending on which column in the TStringList
they are at.
For instance.
adsfoiadjfoaidjfoaidfjo BABABA asdfsd 0101010 skfjlgjljkglsdkgjasaasd BABABA dafdff 0419299 asdaksdjakbkj3409560295 BABABA kjfhan 0923858 dsdddsdasdadasdasdasdgg BABABA dafdff 0419299 45645654654654654654666 BABABA dafdff 0489421 dsdddsdasdadasdasdasdgg CACACA dafdff 0419299
As you can see row two and four have the same value BABABA and also the same number in the end of the line, row five have the same BABABA but not the same number. Row six has the same number but not the same BABABA.
The correct way I want to sort them is
adsfoiadjfoaidjfoaidfjo BABABA asdfsd 0101010 skfjlgjljkglsdkgjasaasd BABABA dafdff 0419299 dsdddsdasdadasdasdasdgg BABABA dafdff 0419299 45645654654654654654666 BABABA dafdff 0489421 asdaksdjakbkj3409560295 BABABA kjfhan 0923858 dsdddsdasdadasdasdasdgg CACACA dafdff 0419299
What I want is to foremost sort after BABABA(column 25-30), and the if there is a match on the numbers, the numbers as well. If the numbers doesn't match it should sort after the BABABA if that doesn't sort it can be sorted in any way.
Upvotes: 1
Views: 1128
Reputation: 43649
So you first want to sort on the second column, and then on the fourth column. Then you need TStringList.CustomSort
.
From the help about the TStringListSortCompare
function type:
Index1 and Index2 are indexes of the items in List to compare. The callback returns:
- a value less than 0 if the string identified by Index1 comes before the string identified by Index2
- 0 if the two strings are equivalent
- a value greater than 0 if the string with Index1 comes after the string identified by Index2.
So if you first compare on the second column, and when equal, proceed comparing on the fourth. Assuming all text is capitalized, all strings are equal in size and with identical syntax, then this should work:
function CompareItems(List: TStringList; Index1, Index2: Integer): Integer;
begin
Result := CompareStr(Copy(List[Index1], 25, 6), Copy(List[Index2], 25, 6));
if Result = 0 then
Result := CompareStr(Copy(List[Index1], 39, 7), Copy(List[Index2], 39, 7));
end;
Usage:
List.CustomSort(CompareItems);
Upvotes: 5
Reputation: 612934
Define your own compare function that picks out that part of your strings that you wish to use for ordering:
function MyCompare(List: TStringList; Index1, Index2: Integer): Integer;
function GetOrderingSubString(const s: string): string;
begin
Assert(Length(s)=45);
Result := Copy(s, 25, 6) + Copy(s, 39, 7);
end;
var
s1, s2: string;
begin
s1 := GetOrderingSubString(List[Index1]);
s2 := GetOrderingSubString(List[Index2]);
Result := CompareText(s1, s2); // or CompareStr, you decide
end;
And pass that function to CustomSort
:
List.CustomSort(MyCompare);
Upvotes: 1