Recent

Author Topic: [SOLVED] Sort on Collections  (Read 671 times)

rforcen

  • Jr. Member
  • **
  • Posts: 52
[SOLVED] Sort on Collections
« on: January 10, 2024, 03:31:13 pm »
i'm trying to sort a generic array using Collections Sort function with below sample app, i get a runtime error: RunError(211) call to abstract method,

how can i solve this?

Code: Pascal  [Select][+][-]
  1. program precgen;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$mode delphi}
  5.  
  6. uses
  7.   SysUtils,
  8.   Generics.Defaults,
  9.   Generics.Collections;
  10.  
  11. type
  12.   TMyRecord = packed record
  13.     Field1: integer;
  14.     Field2: string;
  15.   end;
  16.  
  17.   TMyArray = array of TMyRecord;
  18.  
  19. var
  20.   MyArray: TMyArray;
  21.   I: integer;
  22.  
  23.  
  24.  
  25.   // Specialize TCustomArrayHelper for TMyRecord
  26. type
  27.  
  28.   { TMyRecordHelper }
  29.  
  30.   TMyRecordHelper = class(TCustomArrayHelper<TMyRecord>)
  31.     function CompareRecords(constref Left, Right: TMyRecord): integer;
  32.   end;
  33.  
  34.   { TMyRecordHelper }
  35.  
  36.   function TMyRecordHelper.CompareRecords(constref Left, Right: TMyRecord): integer;
  37.   begin
  38.     Result := Left.Field1 - Right.Field1;
  39.   end;
  40.  
  41. begin
  42.   // Fill the array with some data
  43.   SetLength(MyArray, 3);
  44.   MyArray[0].Field1 := 3;
  45.   MyArray[0].Field2 := 'C';
  46.   MyArray[1].Field1 := 1;
  47.   MyArray[1].Field2 := 'A';
  48.   MyArray[2].Field1 := 2;
  49.   MyArray[2].Field2 := 'B';
  50.  
  51.   // Sort the array by Field1
  52.   TMyRecordHelper.Sort(MyArray, TComparer<TMyRecord>.Construct(TMyRecordHelper.CompareRecords));
  53.  
  54.   // Print the sorted array
  55.   for I := 0 to High(MyArray) do
  56.     WriteLn(MyArray[I].Field1, ' ', MyArray[I].Field2);
  57.  
  58.   ReadLn;
  59. end.
  60.  
« Last Edit: January 10, 2024, 05:17:19 pm by rforcen »

VisualLab

  • Hero Member
  • *****
  • Posts: 614
Re: Sort on Collections
« Reply #1 on: January 10, 2024, 04:16:12 pm »
i'm trying to sort a generic array using Collections Sort function with below sample app, i get a runtime error: RunError(211) call to abstract method,

As the base class for your helper, you used a class that has an abstract method. Abstract methods are only announcements, they have no implementation. The implementation is in derived classes.

The TCustomArrayHelper class has an overloaded Sort method that is public. But inside the implementation of the Sort method (all its variants) there is a call to the QuickSort method. This method is located in the protected section of the TCustomArrayHelper class and is abstract (i.e. there is no implementation in the base class).

You have 2 options:

- implement the QuickSort method in your class (with the override modifier),
- inherit from a class that already has a protected QuickSort method implemented.

Look in the Generics.Collections module and review the code for the TCustomArrayHelper class.
« Last Edit: January 10, 2024, 04:35:02 pm by VisualLab »

Thaddy

  • Hero Member
  • *****
  • Posts: 16348
  • Censorship about opinions does not belong here.
Re: Sort on Collections
« Reply #2 on: January 10, 2024, 04:28:31 pm »
An abstract error usually (always) means you have to either implement it or choose a descendant class that has already implemented it. Basic.
There is nothing wrong with being blunt. At a minimum it is also honest.

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 860
Re: Sort on Collections
« Reply #3 on: January 10, 2024, 05:04:32 pm »
Yeah, try using TArrayHelper instead.

Another thing. I don't think, that it's right. It's about TMyRecordHelper.CompareRecords. In Delphi only class procedures/functions are allowed to be passed as procedure/function of object. Because procedure/function of object requires pointer to some object instance. Either object or class object instance. TMyRecordHelper.CompareRecords isn't bound to any object instance.
« Last Edit: January 10, 2024, 05:18:15 pm by Mr.Madguy »
Is it healthy for project not to have regular stable releases?
Just for fun: Code::Blocks, GCC 13 and DOS - is it possible?

rforcen

  • Jr. Member
  • **
  • Posts: 52
Re: Sort on Collections
« Reply #4 on: January 10, 2024, 05:17:03 pm »
Yeah, try using TArrayHelper instead.
thankx! TArrayHelper did the trick

here's the final working code:

Code: Pascal  [Select][+][-]
  1. program precgen;
  2.  
  3. {$APPTYPE CONSOLE}
  4. {$mode delphi}
  5.  
  6. uses
  7.   SysUtils,
  8.   Generics.Defaults,
  9.   Generics.Collections;
  10.  
  11. type
  12.   TMyRecord = packed record
  13.     Field1: integer;
  14.     Field2: string;
  15.   end;
  16.  
  17.   TMyArray = array of TMyRecord;
  18.  
  19. var
  20.   MyArray: TMyArray;
  21.   I: integer;
  22.  
  23.  
  24.  
  25.   // Specialize TCustomArrayHelper for TMyRecord
  26. type
  27.  
  28.   { TMyArrayHelper }
  29.  
  30.   TMyArrayHelper = class(TArrayHelper <TMyRecord>)
  31.   end;
  32.  
  33.   { cmp func }
  34.  
  35.   function CompareRecords(constref Left, Right: TMyRecord): integer;
  36.   begin
  37.     Result := Left.Field1 - Right.Field1;
  38.   end;
  39.  
  40. begin
  41.   // Fill the array with some data
  42.   SetLength(MyArray, 3);
  43.   MyArray[0].Field1 := 3;
  44.   MyArray[0].Field2 := 'C';
  45.   MyArray[1].Field1 := 1;
  46.   MyArray[1].Field2 := 'A';
  47.   MyArray[2].Field1 := 2;
  48.   MyArray[2].Field2 := 'B';
  49.  
  50.   // Sort the array by Field1
  51.   TMyArrayHelper.Sort(MyArray, TComparer<TMyRecord>.Construct(CompareRecords));
  52.  
  53.   // Print the sorted array
  54.   for I := 0 to High(MyArray) do
  55.     WriteLn(MyArray[I].Field1, ' ', MyArray[I].Field2);
  56.  
  57.   ReadLn;
  58. end.
  59.  

 

TinyPortal © 2005-2018