Delphi - 通用 TList 排序

Delphi - generic TList sort

我正在使用 Generics.Collections.TList 和排序方法。它工作正常,但我想最后对空值或空值进行排序。按升序和降序排序。如何实现?

这是我的排序函数:

function TForm.SortByColumn(ColumnID: integer; SortDirRev: integer):boolean;
var
  Comparison: TComparison<TSymData>;
begin
  Result := false;

  Comparison := nil;

  if ColumnID = 0 then
    begin
      Comparison := function(const Left, Right: TSymData): integer
      begin
        Result := SortDirRev * TComparer<string>.Default.Compare(Left.Name,Right.Name);
      end;
    end
  else
    begin
      Comparison := function(const Left, Right: TSymData): integer
      begin
        Result := SortDirRev * TComparer<string>.Default.Compare(Left.Sub[ColumnID-1],Right.Sub[ColumnID-1]);
      end;
    end;

  if assigned(Comparison) then
    FSymList.Sort(TComparer<TSymData>.Construct(Comparison));

end;

您只需要提供一个将空值考虑在内的比较函数。

比较函数是一个接受两项 A 和 B 的函数,returns -1 如果 A 应该在 B 之前,+1 如果 A 应该在 B 之后,如果考虑 A 和 B 则为 0等于。

例如,要使用标准字符串比较器对字符串列表 L 进行排序,您可以这样做(仅供参考)

L.Sort(
  TComparer<string>.Construct(
    function(const Left, Right: string): Integer
    begin
      Result := CompareStr(Left, Right)
    end
  )
);

要根据字符串长度排序,执行

L.Sort(
  TComparer<string>.Construct(
    function(const Left, Right: string): Integer
    begin
      Result := CompareValue(Left.Length, Right.Length)
    end
  )
);

现在,如果您想正常对字符串进行排序,除了您明确要求所有空字符串排在第一位之外,您可以这样做

L.Sort(
  TComparer<string>.Construct(
    function(const Left, Right: string): Integer
    begin
      if Left.IsEmpty and not Right.IsEmpty then
        Result := -1
      else if not Left.IsEmpty and Right.IsEmpty then
        Result := +1
      else
        Result := CompareStr(Left, Right)
    end
  )
);

要将空字符串放在最后,请执行

L.Sort(
  TComparer<string>.Construct(
    function(const Left, Right: string): Integer
    begin
      if Left.IsEmpty and not Right.IsEmpty then
        Result := +1
      else if not Left.IsEmpty and Right.IsEmpty then
        Result := -1
      else
        Result := CompareStr(Left, Right)
    end
  )
);