如果我有一个包含更多字段的泛型列表,例如:
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进行排序。 那么我的问题是:我可以使用一个唯一的构造比较来做我的列表吗?
非常感谢您的帮助。
答案 0 :(得分: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);
答案 1 :(得分:2)
我打算在你的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 :(得分:0)
考虑领域优先事项的方法:
OverallCompareResult:= Sum(CompareResult [i] *(1 shl Priority [i]))
(1 shl Priority [i] = 2 ^ Priority [i])
您的示例的优先级[]:(4,1,3,2,5)
CompareResult必须在(-1,0,1)
中