【问题标题】:order List with criteria choose to runtime带有条件的订单列表选择运行时
【发布时间】:2011-12-04 15:07:27
【问题描述】:

如果我有一个包含更多字段的泛型列表,例如:

PMyList = record 
  Field1, Field2, ... FieldN : Integer;
end;
TMyList = List<PMyList>;

要使用标准选择运行时的列表(例如:field2 然后 field2,或者:field3 然后 field1 然后 field2 等)有一些解决方案,或者我需要为我想要的所有可能的顺序组合做一个比较构造?

我的想法是,如果记录是 N 个字段,我想到了一个这样定义的数组:

MyArray = array [1..n] of Integer;

并为确定 sord 标准的数组元素分配一个渐进值,例如,如果 MyArray 为:

MyArray = (5, 1, 3, 4, 2)

意味着我的列表需要首先对 field5 进行排序,然后是 field1,然后是 field3,然后是 field4,然后是 field2。 那么我的问题是:我可以只为我的列表使用一个构造比较吗?

非常感谢您的帮助。

【问题讨论】:

标签: delphi delphi-xe2


【解决方案1】:

我将以您的previous question 为基础。我还要将MyArray 重命名为FieldPriority

所以,FieldPriority[1] 标识主要比较字段,FieldPriority[2] 标识次要比较字段,依此类推。

有了这个,你的比较函数看起来像这样:

type
  TMyRecord  = record
    Value: array [1..5] of Integer;
  end;

function Compare(const Left, Right: TMyRecord): Integer;
var
  i, Field: Integer;
begin
  for i := 1 to 5 do
  begin
    Field := FieldPriority[i];
    Result := CompareInt(Left.Value[Field], Right.Value[Field]);
    if Result<>0 then
      exit;
  end;
end;

如果将记录中的整数声明为数组而不是单独声明,则效果会更好。这样您就可以像我在这里所做的那样对它们进行索引。

当然,这都可以推广到处理任意大小的数组。

【讨论】:

    【解决方案2】:

    如果我没听错的话:

    Comparer := TComparer<PMyList>.Construct(
         function(const Left, Right: PMyList): Integer
         var LV, RV, x: Integer;
         begin
            for x := Low(MyArray) to High(MyArray) do begin
               case MyArray[x] of
                 1: begin
                    LV := Left.Field1;
                    RV := Right.Field1;
                 end;
                 2: begin
                    LV := Left.Field2;
                    RV := Right.Field2;
                 end;
                 ...
                 else raise Exception.Create('Unhandled fileld index: '+IntToStr(MyArray[x]));
               end;
               Result := LV - RV;
               if(Result <> 0)then Break;
            end;
         end);
    

    【讨论】:

      【解决方案3】:

      一种考虑字段优先级的方法:

      OverallCompareResult := Sum(CompareResult[i] * (1 shl Priority[i]))

      (1 shl 优先级[i] = 2 ^ 优先级[i])

      您的示例的优先级 []:(4, 1, 3, 2, 5)

      CompareResult 必须在 (-1, 0, 1) 中

      【讨论】:

        猜你喜欢
        • 2011-11-22
        • 1970-01-01
        • 2013-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-19
        • 1970-01-01
        相关资源
        最近更新 更多