Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2      [все]
 Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Есть запись

TMyRec = record
  field1,
  field2,
  field3: string;
end;


Есть массив

a: array of TMyRec;


есть его сортировка

for i:=1 to n-1 do
for j:=i+1 to n do
  if a[i].field1>a[j].field1 then
    begin
       tmp:=a[i];
       a[i]:=a[j];
       a[j]:=tmp;
    end;


Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле, чтобы не размножать сортировку для каждого поля в коде? :)
31 май 21, 08:59    [22329116]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Gerasimenko
Member

Откуда:
Сообщений: 4664
antox,

передавать индекс сортируемого поля как параметр
31 май 21, 09:01    [22329117]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
x1ca4064
Member

Откуда:
Сообщений: 1273
antox

Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле, чтобы не размножать сортировку для каждого поля в коде? :)


Передавать в сортировку функцию сравнения:

function Cmp(a,b:pointer):integer
31 май 21, 09:07    [22329122]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Gerasimenko
antox,

передавать индекс сортируемого поля как параметр


а как обратиться по индексу?

a[i].field1>a[j].field1


или писать Case на все случаи?

case indx of
0: begin
  for i:=1 to n-1 do
  for j:=i+1 to n do
    if a[i].field1>a[j].field1 then
      begin
         tmp:=a[i];
         a[i]:=a[j];
         a[j]:=tmp;
      end;
1: begin
  for i:=1 to n-1 do
  for j:=i+1 to n do
    if a[i].field2>a[j].field2 then
      begin
         tmp:=a[i];
         a[i]:=a[j];
         a[j]:=tmp;
      end;
2: begin
  for i:=1 to n-1 do
  for j:=i+1 to n do
    if a[i].field3>a[j].field3 then
      begin
         tmp:=a[i];
         a[i]:=a[j];
         a[j]:=tmp;
      end;
end;


Можно как-то хотя бы через указатели (не знаю, как это сделать)?

 fld : point;
begin
case indx of
0: fld := ^field1;
1: fld := ^field2;
2: fld := ^field2;
end;
  for i:=1 to n-1 do
  for j:=i+1 to n do
    if a[i].fld^ >a[j].fld^ then
      begin
         tmp:=a[i];
         a[i]:=a[j];
         a[j]:=tmp;
      end;
end;
31 май 21, 09:16    [22329126]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
x1ca4064
antox

Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле, чтобы не размножать сортировку для каждого поля в коде? :)


Передавать в сортировку функцию сравнения:

function Cmp(a,b:pointer):integer


А как это реализовать на примере?
31 май 21, 09:18    [22329130]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Gerasimenko
Member

Откуда:
Сообщений: 4664
antox,

TMyRec = record
  field1,
  field2,
  field3: string;
end;


vs

TMyRec = record
  field: array [0..2] of string;
end;
31 май 21, 09:21    [22329131]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Gerasimenko,

Так неудобно обращаться к полям :) Это можно запутаться, где чё хранится
31 май 21, 09:27    [22329133]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
x1ca4064
Member

Откуда:
Сообщений: 1273
antox

А как это реализовать на примере?


type
  TCmpFun=function (a,b:pointer):integer;

function Cmp1(a,b:pointer):integer;
begin
  if TMyRec(a^).field1>TMyRec(b^).fileld1 then Result=1
  else if TMyRec(a^).field1<TMyRec(b^).fileld1 then Result:=-1
  else Result:=0;
end;

procedure MySort(Data:array of TMyRec;CmpFun:TCmpFun);
begin
  ....
  case CmpFun(@Data[i],@Data[j]) of
  -1:
    ....
  1:
    ...
  end;
end;

begin
  MySort(Data,@Cmp1);
end.


Можно и без указателей, если не нужна универсальность сортировки

Сообщение было отредактировано: 31 май 21, 09:33
31 май 21, 09:39    [22329139]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
x1ca4064,

function Cmp1(a,b:pointer):integer;
begin
  if TMyRec(a^).field1>TMyRec(b^).fileld1 then Result=1
  else if TMyRec(a^).field1<TMyRec(b^).fileld1 then Result:=-1
  else Result:=0;
end;


Так тут все равно напрямую указано имя поля field1, а мне что бы по любому имени, или имеется в виду, что для каждого поля будет такая функция:

function sField1(a,b:pointer):integer;
begin
  if TMyRec(a^).field1>TMyRec(b^).fileld1 then Result=1
  else if TMyRec(a^).field1<TMyRec(b^).fileld1 then Result:=-1
  else Result:=0;
end;

function sField2(a,b:pointer):integer;
begin
  if TMyRec(a^).field2>TMyRec(b^).fileld2 then Result=1
  else if TMyRec(a^).field2<TMyRec(b^).fileld2 then Result:=-1
  else Result:=0;
end;

function sField3(a,b:pointer):integer;
begin
  if TMyRec(a^).field3>TMyRec(b^).fileld3 then Result=1
  else if TMyRec(a^).field3<TMyRec(b^).fileld3 then Result:=-1
  else Result:=0;
end;
31 май 21, 09:56    [22329150]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Fr0sT-Brutal
Member

Откуда:
Сообщений: 755
antox
Так тут все равно напрямую указано имя поля field1, а мне что бы по любому имени, или имеется в виду, что для каждого поля будет такая функция:

Чтобы не указывать, делай массив. Обращаться можно через именованные константы, чтобы не запутываться (rec.Fields[fField1]). Теоретически можно и через RTTI, но ты вряд ли осилишь на текущем уровне, раз уж такие вопросы задаешь
31 май 21, 10:26    [22329158]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
x1ca4064
Member

Откуда:
Сообщений: 1273
antox
x1ca4064,
Так тут все равно напрямую указано имя поля field1, а мне что бы по любому имени, или имеется в виду, что для каждого поля будет такая функция:


Да, для каждого поля своя функция сравнения, ее прототип можно сделать таким:

TCmpFun=function (const a,b:TMyRec):integer;

но тогда будет тяжко написать общую процедуру сортировки, которая позволит сортировать почти все:

procedure MySort(const ArrayData;const ElementCount,ElementSize:integer;CmpFun:TCmpFun)
31 май 21, 10:53    [22329178]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Fr0sT-Brutal
antox
Так тут все равно напрямую указано имя поля field1, а мне что бы по любому имени, или имеется в виду, что для каждого поля будет такая функция:

Чтобы не указывать, делай массив. Обращаться можно через именованные константы, чтобы не запутываться (rec.Fields[fField1]). Теоретически можно и через RTTI, но ты вряд ли осилишь на текущем уровне, раз уж такие вопросы задаешь


Не благодари ;)

procedure Sort(field_name: string);
var
  i,j,n,f,findx: integer;
  val_i, val_j,  tmp: TMyRec;
  rtype: TRTTIType;
  fields: TArray<TRttiField>;
begin
  n:= High(A);

  rtype := TRTTIContext.Create.GetType(TypeInfo(TMyRec));
  fields := rtype.GetFields;

  findx:=-1;

  for f := Low(fields) to High(fields) do
    if fields[f].Name = field_name then findx := f;

  if findx < 0 then Exit;


  for i:=1 to n-1 do
  for j:=i+1 to n do
    begin
      val_i := a[i];
      val_j := a[j];

      if fields[findx].GetValue(@val_i).ToString > fields[findx].GetValue(@val_j).ToString then
        begin
          tmp:=a[i];
          a[i]:=a[j];
          a[j]:=tmp;
        end;
    end;
end;
31 май 21, 11:18    [22329193]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12901
antox
Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле
TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field1, AItem2.Field1);
  end;
));

TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field2, AItem2.Field2);
  end;
));


Сообщение было отредактировано: 31 май 21, 12:06
31 май 21, 12:14    [22329235]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12901
Или
TMyRec = record
  field1,
  field2,
  field3: string;
  class function SortByField1(const AItem1, AItem2: TMyRec): Integer;
  class function SortByField2(const AItem1, AItem2: TMyRec): Integer;
end;

class function TMyRec.SortByField1(const AItem1, AItem2: TMyRec): Integer;
begin
   Result := AnsiCompareStr(AItem1.Field1, AItem2.Field1);
end;

class function TMyRec.SortByField2(const AItem1, AItem2: TMyRec): Integer;
begin
   Result := AnsiCompareStr(AItem1.Field2, AItem2.Field2);
end;

TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(TMyRec.SortByField1);
31 май 21, 12:19    [22329239]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
А вот они - новые технологии ;) Спасибо
31 май 21, 13:00    [22329278]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
_Vasilisk_
antox
Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле
TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field1, AItem2.Field1);
  end;
));

TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field2, AItem2.Field2);
  end; //<- после end точку с запятой убрать
));


Работает отлично, точка с запятой лишняя
31 май 21, 13:06    [22329280]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
DimaBr
Member

Откуда:
Сообщений: 12091
for i:=1 to n-1 do
  for j:=i+1 to n do
    if (Index=0 and a[i].field1 > a[j].field1) or
       (Index=2 and a[i].field2 > a[j].field2) or
       (Index=3 and a[i].field3 > a[j].field3) then 
    begin
       tmp:=a[i];
       a[i]:=a[j];
       a[j]:=tmp;
    end;
31 май 21, 13:47    [22329310]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
_Vasilisk_
antox
Как (с помощью крутых и новейших технологий Delphi) вместо field1 подставлять любое поле
TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field1, AItem2.Field1);
  end;
));

TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    Result := AnsiCompareStr(AItem1.Field2, AItem2.Field2);
  end;
));


Модернизация под любое поле:

procedure SuperSortArray(field_name: string);
var
  rtype: TRTTIType;
  fields: TArray<TRttiField>;
  f,findx: Integer;
  par_a, par_b: string;
begin
  rtype := TRTTIContext.Create.GetType(TypeInfo(TMyRec));
  fields := rtype.GetFields;

  findx:=-1;

  for f := Low(fields) to High(fields) do
    if fields[f].Name = field_name then findx := f;

  if findx < 0 then Exit;

  TArray.Sort<TFieldTovar>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  begin
    par_a := fields[findx].GetValue(@AItem1).AsString;
    par_b := fields[findx].GetValue(@AItem2).AsString;
    Result := AnsiCompareStr(par_a, par_b);
  end
  ));
end;
31 май 21, 13:58    [22329321]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
DimaBr
Member

Откуда:
Сообщений: 12091
antox

Модернизация под любое поле:

А теперь для вещественных полей напишите
31 май 21, 14:04    [22329324]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
rgreat
Member

Откуда:
Сообщений: 6711
Суровые извращения. Непонятно только зачем.
31 май 21, 14:08    [22329330]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
DimaBr
antox

Модернизация под любое поле:

А теперь для вещественных полей напишите


:( сортирует, как текст
31 май 21, 14:12    [22329333]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
rgreat
Суровые извращения. Непонятно только зачем.


Так, вроде, самый простой вариант сортировки массива записей по полям... Не знаю, как проще можно это сделать
31 май 21, 14:14    [22329334]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
DimaBr
antox

Модернизация под любое поле:

А теперь для вещественных полей напишите


    //Result := AnsiCompareStr(par_a, par_b);
    Result := CompareValue(par_a, par_b);


Работает
31 май 21, 14:20    [22329341]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
DimaBr
Member

Откуда:
Сообщений: 12091
Куда проще ? 22329310
31 май 21, 14:20    [22329342]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
DimaBr,

Так для этого придется для сортировки каждого массива (а у них разные поля) писать все поля в процедуру :) Руки отвалятся

И так же тоже числа в сортируются как текст, как я понял

Сообщение было отредактировано: 31 май 21, 14:16
31 май 21, 14:24    [22329343]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
DimaBr
Member

Откуда:
Сообщений: 12091
antox

    //Result := AnsiCompareStr(par_a, par_b);
    Result := CompareValue(par_a, par_b);

Работает

Но при этом string не сравнивает, беда......
31 май 21, 14:25    [22329344]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 32405

зафигакай сравнение Variant-ов.
универсально, но медленно.

либо те большие, но по 5 рублей (вчера), либо эти маленькие по 3, но сегодня. (С)

Posted via ActualForum NNTP Server 1.5

31 май 21, 14:29    [22329349]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12901
DimaBr
Но при этом string не сравнивает, беда...
По идее вот так может заработать
TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  var
    par_a, par_b: TValue;
  begin
    par_a := fields[findx].GetValue(@AItem1);
    par_b := fields[findx].GetValue(@AItem2);
    Result := TComparer<TValue>.Default.Compare(par_a, par_b);
  end
));


Сообщение было отредактировано: 31 май 21, 14:40
31 май 21, 14:49    [22329362]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Мимопроходящий

зафигакай сравнение Variant-ов.
универсально, но медленно.

либо те большие, но по 5 рублей (вчера), либо эти маленькие по 3, но сегодня. (С)


уже сделал, но не красиво...
31 май 21, 14:52    [22329365]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 32405

31.05.2021 14:52, antox пишет:
> уже сделал, но не красиво...

одно яичко выше? (С)

Posted via ActualForum NNTP Server 1.5

31 май 21, 14:54    [22329368]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
_Vasilisk_
DimaBr
Но при этом string не сравнивает, беда...
По идее вот так может заработать
TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  var
    par_a, par_b: TValue;
  begin
    par_a := fields[findx].GetValue(@AItem1);
    par_b := fields[findx].GetValue(@AItem2);
    Result := TComparer<TValue>.Default.Compare(par_a, par_b);
  end
));


Немного подправил (Variant вместо TValue) и заработало:

    par_a := fields[findx].GetValue(@AItem1).AsVariant;
    par_b := fields[findx].GetValue(@AItem2).AsVariant;

    Result := TComparer<[b]Variant[/b]>.Default.Compare(par_a, par_b);
31 май 21, 14:57    [22329372]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Также работает и эта конструкция:

procedure Sort(field_name: string);
var
  i,j,n,f,findx: integer;
  val_i, val_j,  tmp: TMyRec;
  rtype: TRTTIType;
  fields: TArray<TRttiField>;
begin
  n:= High(A);

  rtype := TRTTIContext.Create.GetType(TypeInfo(TMyRec));
  fields := rtype.GetFields;

  findx:=-1;

  for f := Low(fields) to High(fields) do
    if fields[f].Name = field_name then findx := f;

  if findx < 0 then Exit;


  for i:=1 to n-1 do
  for j:=i+1 to n do
    begin
      val_i := a[i];
      val_j := a[j];

      if fields[findx].GetValue(@val_i).AsVariant> fields[findx].GetValue(@val_j).AsVariantthen
        begin
          tmp:=a[i];
          a[i]:=a[j];
          a[j]:=tmp;
        end;
    end;
end;
31 май 21, 14:59    [22329374]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Мимопроходящий

31.05.2021 14:52, antox пишет:
> уже сделал, но не красиво...

одно яичко выше? (С)


третье появилось :D
31 май 21, 14:59    [22329375]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
DimaBr
Member

Откуда:
Сообщений: 12091
Более чем уверен, что через год, смотря на это синтаксический мусор, вы будите думать, а что же тут происходит?
31 май 21, 15:02    [22329378]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
antox
Member

Откуда: РФ
Сообщений: 1267
Возникает вопрос, что быстрее будут работать

for i:=1 to n-1 do
  for j:=i+1 to n do
    begin
      val_i := a[i];
      val_j := a[j];

      if fields[findx].GetValue(@val_i).AsVariant> fields[findx].GetValue(@val_j).AsVariantthen
        begin
          tmp:=a[i];
          a[i]:=a[j];
          a[j]:=tmp;
        end;
    end;


или

TArray.Sort<TMyRec>(a, TComparer<TMyRec>.Construct(
  function (const AItem1, AItem2: TMyRec): Integer
  var
    par_a, par_b: TValue;
  begin
    par_a := fields[findx].GetValue(@AItem1);
    par_b := fields[findx].GetValue(@AItem2);
    Result := TComparer<Variant>.Default.Compare(par_a, par_b);
  end
));
31 май 21, 15:03    [22329379]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
rgreat
Member

Откуда:
Сообщений: 6711
antox,

Premature optimization.

Тромозить будет не это.
31 май 21, 15:20    [22329384]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12901
antox
Возникает вопрос, что быстрее будут работать
Очевидно же, что второй вариант. Быстрая сортировка всегда быстрее пузырьковой
31 май 21, 15:36    [22329391]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
rgreat
Member

Откуда:
Сообщений: 6711
_Vasilisk_,

Тьфу, блин.
Я на разницу в приведении типов смотрел а на то что они там в первом случае еще метод и пузырька зачем-то приделал.
31 май 21, 15:52    [22329400]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2498
_Vasilisk_
antox
Возникает вопрос, что быстрее будут работать
Очевидно же, что второй вариант. Быстрая сортировка всегда быстрее пузырьковой

Вообще - не всегда, но первый вариант - ниразу не пузырьковая сортировка.
31 май 21, 17:08    [22329441]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12901
Maxim Rusov
первый вариант - ниразу не пузырьковая сортировка.
А что это тогда?
31 май 21, 17:49    [22329464]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
ъъъъъ
Member

Откуда:
Сообщений: 2125
_Vasilisk_
Maxim Rusov
первый вариант - ниразу не пузырьковая сортировка.
А что это тогда?

Пузырькова сортировка в цикле переставляет элементы до тех пор, пока не случится пустой проход.
А тут - какой-то декартов п....ц.
31 май 21, 17:52    [22329469]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Maxim Rusov
Member

Откуда: Москва-Питер
Сообщений: 2498
_Vasilisk_,

https://www.toptal.com/developers/sorting-algorithms
31 май 21, 18:00    [22329475]     Ответить | Цитировать Сообщить модератору
 Re: Сортировка массива записей по произвольному полю записи  [new]
Uridian
Member

Откуда: Lobnya
Сообщений: 239
antox
Так тут все равно напрямую указано имя поля field1, а мне что бы по любому имени, или имеется в виду, что для каждого поля будет такая функция


чтобы не указывать имя поля при сортировке по любому из них:

+
unit TestTypes;
interface
uses System.SysUtils, Generics.Defaults, Generics.Collections;
type
  TMyRec = record
    type TIndex = 1..3;
    var
    field1,
    field2,
    field3: string;
    function Field (idx: TIndex): string;
  end;
  TMyArray = TArray <TMyRec>;
implementation
function TMyRec.Field(idx: TIndex): string;
begin
  case idx of              // не особо элегантно, но работает
    1: Result := field1;
    2: Result := field2;
    3: Result := field3;
  end;
end;
procedure DoSomething (idx: TMyRec.TIndex);
var
  a: TMyArray;
begin
  SetLength (a, 1000);
  TArray.Sort <TMyRec> (a, TComparer <TMyRec>.Construct (
    function (const L,R: TMyRec): Integer
    begin
      Result := AnsiCompareStr (L.Field(idx), R.Field(idx));
    end
    ));
end;
end.
7 июн 21, 12:29    [22332205]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Delphi Ответить