Einzelnen Beitrag anzeigen

nahpets
(Gast)

n/a Beiträge
 
#7

Re: Sortierung von Stringlisten ab unbestimmter Position

  Alt 14. Okt 2008, 09:24
Hallo,

nach einigem Rumprobieren und Fehlersuche ist nun folgendes übriggeblieben:
Delphi-Quellcode:
unit SortStringList;

interface

uses Classes;

type
  rPosData = record
    StartPos : integer;
    NextPos : integer;
  end;

  arPosData = Array of rPosData;

type
  tSortStringList = class(TStringList)
  private
    fSortColumn : Integer;
    fSortDescending : Boolean;
  protected
    function GetStartPos(s : String; Delimiter : Char; SortColumn : Integer) : Integer;
    function GetNextPos (s : String; Delimiter : Char; iStartPos : Integer) : Integer;
  public
    procedure Compare;
  published
    property SortColumn : Integer Read FSortColumn Write fSortColumn Default 0;
    property SortDescending : Boolean Read fSortDescending Write fSortDescending Default False;
  end;

implementation

uses StrUtils, SysUtils;

// Stelle im String ermitteln, ab der sortiert werden soll.
Function TSortStringList.GetStartPos(s : String; Delimiter : Char; SortColumn : Integer) : Integer;
Var
         iCount : Integer;
         iPos : Integer;
begin
  iCount := 0;
  iPos := 0;
  Repeat
    iPos := PosEx(Delimiter,s,iPos + 1);
    Inc(iCount);
  until (iCount = SortColumn) or (iPos = 0);
  Result := iPos;
end;

// Länge des zu sortierenden Strings ermitteln.
Function TSortStringList.GetNextPos(s : String; Delimiter : Char; iStartPos : Integer) : Integer;
begin
  Result := PosEx(Delimiter,s,iStartPos);
  If Result = 0 Then Result := Length(s) Else Result := Result - iStartPos + 2;
end;

function MyCompare(List: TStringList; Index1, Index2: Integer): Integer;
Var
         iStartPos1 : Integer;
         iNextPos1 : Integer;
         iStartPos2 : Integer;
         iNextPos2 : Integer;
begin
  with List As TSortStringList do begin
    iStartPos1 := GetStartPos(List[Index1],Delimiter,SortColumn);
    iNextPos1 := GetNextPos(List[Index1],Delimiter,iStartPos1 + 1);
    iStartPos2 := GetStartPos(List[Index2],Delimiter,SortColumn);
    iNextPos2 := GetNextPos(List[Index2],Delimiter,iStartPos2 + 1);
    if List.CaseSensitive then begin
      Result := AnsiCompareStr(Copy(List[Index1],iStartPos1,iNextPos1),
                                Copy(List[Index2],iStartPos2,iNextPos2));
    end else begin
      Result := AnsiCompareText(Copy(List[Index1],iStartPos1,iNextPos1),
                                 Copy(List[Index2],iStartPos2,iNextPos2));
    end;
    If Result <> 0 then begin
      if SortDescending then Result := Result * (-1);
    end;
  end;
end;

procedure TSortStringList.Compare;
begin
  Self.CustomSort(MyCompare);
end;

end.
Den Aufbau eines Array mit Startpos... habe ich wieder entfernt, da der Inhalt dieses Arrays nicht immer mit der Reihenfolge der Einträge in der Stringliste synchron zu halten war. Wo da die Ursache liegt, habe ich nicht herausfinden können. Dafür kann man in dieser Fassung nun auch absteigend sortieren lassen.
  Mit Zitat antworten Zitat