如何按多个字段对记录列表进行排序?

时间:2012-12-17 12:38:02

标签: delphi sorting

我想首先按x坐标排序坐标列表,然后按y坐标排序:

Orginal: (7,8)(10,22)(7,3)(5,10)(20,14)(7,10)(7,3)

First Step by x: (5,10)(7,8)(7,3)(7,10)(7,3)(10,22)(20,14)

Second Step by y: (5,10)(7,3)(7,3)(7,8)(7,10)(10,22)(20,14)

我已经有一个适用于第一步的功能:

function SortCoords(Item1: Pointer; Item2: Pointer): Integer;
var
line1 : Coords;
line2 : Coords;
begin
  line1 :=  Coords;(Item1);
  line2 :=  Coords;(Item2);

  if (line1.X < line2.X) then 
    result := -1
  else if (line1.X > line2.X) then 
     result := 1
  else
     result := 0;

end; 

但我没有第二步。

3 个答案:

答案 0 :(得分:7)

如果您想要按辅助键排序的项目,这只有在第一个键相等时才会很重要。在您的示例中,这是result := 0;案例。

这样的事情:

if (line1.X < line2.X) then 
    result := -1
  else if (line1.X > line2.X) then 
     result := 1
  else if (line1.Y < line2.Y) then 
    result := -1
  else if (line1.Y > line2.Y) then 
     result := 1
  else
     result := 0;

可能做你想做的事。

答案 1 :(得分:2)

type
 TPC=Class
   x,y:Integer;
   Constructor Create(ax,ay:Integer);
 End;


function SortCoords(Item1: Pointer; Item2: Pointer): Integer;
var
line1 : TPC;
line2 : TPC;
begin
  line1 :=  TPC(Item1);
  line2 :=  TPC(Item2);

  if (line1.X < line2.X) then
    result := -1
  else if (line1.X > line2.X) then
     result := 1
  else
     begin
        if (line1.y < line2.y) then
          result := -1
        else if (line1.y > line2.y) then
          result := 1
        else result := 0;
     end;
end;

procedure TForm4.Button1Click(Sender: TObject);
var
  l:TList;
  I: Integer;

begin
  l := TList.Create;
  try
    l.Add(TPC.Create(7,8));
    l.Add(TPC.Create(10,22));
    l.Add(TPC.Create(5,10));
    l.Add(TPC.Create(20,14));
    l.Add(TPC.Create(7,10));
    l.Add(TPC.Create(7,3));
    l.Sort(SortCoords);
    for I := 0 to l.Count- 1 do
      begin
      memo1.lines.add(Format('x: %d  y: %d',[TPC(l[i]).x,TPC(l[i]).y]));
      TPC(l[i]).Free;
      end;
  finally
    l.Free;
  end;

end;

{ TPC }

constructor TPC.Create(ax, ay: Integer);
begin
   x := ax;
   y := ay;
end;

答案 2 :(得分:2)

您可以使用'开箱即用'Sort方法。

输出
// data initialization 

Dump;

TArray.Sort<Coords1>(c1);
TArray.Sort<Coords2>(c2);
c3.Sort;

Dump;

将是

7: [ (7; 8), (10; 22), (7; 3), (5; 10), (20; 14), (7; 10), (7; 3)]
7: [ (7; 8), (10; 22), (7; 3), (5; 10), (20; 14), (7; 10), (7; 3)]
7: [ (7; 8), (10; 22), (7; 3), (5; 10), (20; 14), (7; 10), (7; 3)]

7: [ (5; 10), (7; 3), (7; 3), (7; 8), (7; 10), (10; 22), (20; 14)]
7: [ (5; 10), (7; 3), (7; 3), (7; 8), (7; 10), (10; 22), (20; 14)]
7: [ (5; 10), (7; 3), (7; 3), (7; 8), (7; 10), (10; 22), (20; 14)]

数据

type
  Coord = Integer;
  Coords1 = record X,Y: Coord; end;  Coords2 = TPair< Coord, Coord >;
  CoordsList1 = array of Coords1;    CoordsList2 = TArray< Coords2 >;
  CoordsList3 = class (TList < Coords1 >) public function ToString: string; override; end;

var c1: CoordsList1; c2: CoordsList2; c3: CoordsList3;

完整来源位于http://pastebin.ca/2294517 没有“嵌套if”比较功能,但如果您愿意,可以提供一个。