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

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

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

Работает

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

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

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

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

Posted via ActualForum NNTP Server 1.5

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

Откуда: Украина, Харьков
Сообщений: 12885
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

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

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

Откуда:
Сообщений: 12089
Более чем уверен, что через год, смотря на это синтаксический мусор, вы будите думать, а что же тут происходит?
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

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

Premature optimization.

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

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

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

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

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

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

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

Откуда:
Сообщений: 2114
_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]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Delphi Ответить