簡體   English   中英

如何用評論對字符串列表進行排序

[英]How to sort stringlist with comments

我有帶注釋的字符串列表(如Ini文件部分的內容):

;comment c
c=str1
;comment b
b=str2
;comment a
a=str3

任何想法如何將列表按名稱排序為:

;comment a
a=str3
;comment b
b=str2
;comment c
c=str1

配對時,注釋應與配對鏈接

一種選擇是將TStringList內容解析為第二個列表,該列表將名稱,值和注釋字符串分開並將其分組在一起,然后根據需要在名稱上對該列表進行排序,然后用排序后的組重新填充TStringList 例如:

uses
  ...
  System.Classes,
  System.SysUtils,
  System.Generics.Defaults,
  System.Generics.Collections,
  System.StrUtils,
  System.Types;

type
  ItemInfo = record
    LeadingText,
    Name,
    Value: string;
  end;

  ItemInfoComparer = class(TComparer<ItemInfo>)
  public
    function Compare(const Left, Right: ItemInfo): Integer; override;
  end;

function ItemInfoComparer.Compare(const Left, Right: ItemInfo): Integer;
begin
  if (Left.Name <> '') and (Right.Name <> '') then
    Result := AnsiCompareStr(Left.Name, Right.Name)
  else if (Left.Name <> '') then
    Result := -1
  else
    Result := 1;
end;

procedure SortMyList(List: TStringList);
var
  Compare: IComparer<ItemInfo>;
  Items: TList<ItemInfo>;
  Info: ItemInfo;
  I: Integer;
  InText: Boolean;
  S: String;
begin
  Compare := ItemInfoComparer.Create;
  Items := TList<ItemInfo>.Create(Compare);
  try
    Items.Capacity := List.Count;
    InText := False;

    for I := 0 to List.Count-1 do
    begin
      S := Trim(List[i]);
      if (S = '') or (S[1] = ';') then
      begin
        if InText then
          Info.LeadingText := Info.LeadingText + #13 + List[i]
        else
        begin
          Info.LeadingText := List[i];
          InText := True;
        end;
      end else
      begin
        Info.Name := List.Names[I];
        Info.Value := List.ValueFromIndex[I];
        Items.Add(Info);
        Info := Default(ItemInfo);
        InText := False;
      end;
    end;

    if InText then
      Items.Add(Info);

    Items.Sort;

    List.Clear;
    for I := 0 to Items.Count-1 do
    begin
      Info := Items[I];

      if Info.LeadingText <> '' then
      begin
        for S in SplitString(Info.LeadingText, #13) do
          List.Add(S);
      end;

      if Info.Name <> '' then
        List.Add(Info.Name + '=' + Info.Value);
    end;
  finally
    Items.Free;
  end;
end;

這是一個簡單的過程,可以對貨物進行分類並處理貨物。 我還在文件末尾添加了用於處理注釋的代碼。

這將適用於不具有Remy回答中的泛型或高級類型的Delphi的較舊版本(為使用較舊版本的用戶提供了方便)

function SortKeys(List: TStringList; Index1, Index2: Integer): Integer;
begin
  result := CompareText(List.Names[Index1], List.Names[Index2]);
end;


Procedure SortStringListWithComments(AStrings: TStrings);
var
 LCargoText: TStringList;
 LSortedText : TStringList;
 s: string;
 i : integer;
begin
  LCargoText := nil; 
  LSortedText := TStringList.Create;
  try
    for i := 0 to AStrings.count-1 do
    begin
      s := Trim(AStrings[i]);
      if (s='') or (s[1] = ';') then //LCargoText and blank lines attached to sorted strings (Boolean short circuit assumed here) 
       begin
        if LCargoText = nil then
          LCargoText := TStringList.Create;
        LCargoText.Add(AStrings[i]);
      end
      else
      begin
        LSortedText.AddObject(AStrings[i], LCargoText);
        LCargoText := nil; //set nil to deal with cases where we have no   comments for a following key value pair
      end;

    end;

    LSortedText.CustomSort(SortKeys);

    // LSortedText.sort -  will cause a1=x to be sorted before a=x

    AStrings.clear;

    for i := 0 to LSortedText.count-1 do
    begin
      if  LSortedText.objects[i] <> nil then
      begin
        AStrings.AddStrings(TStringList(LSortedText.Objects[i]));
        LSortedText.Objects[i].Free;
      end;
      AStrings.Add(LSortedText[i]);
    end;

    if LCargoText <> nil then
    begin
      AStrings.AddStrings(LCargoText) ; //comments orphaned at the end of the file
      LCargoText.Free;
    end;
  finally
    LSortedText.Free;
  end; 
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM