Recent

Author Topic: append new record to array using array operators  (Read 827 times)

MMarie

  • New Member
  • *
  • Posts: 48
  • Right, lets bodge this pisspot
    • Homepage
append new record to array using array operators
« on: December 06, 2025, 07:43:47 am »
good morning :)

is it possible for me to do something akin to this when using {$mode objfpc} and ArrayOperators?

Code: Pascal  [Select][+][-]
  1. type
  2.   TSomeRecord = record
  3.     startCol, endCol: SizeInt;
  4.   end;
  5.  
  6.   TSomeRecords = array of TSomeRecord;
  7.  
  8. procedure SomeProc;
  9. var
  10.   recs: TSomeRecords;
  11. begin
  12.   {...}
  13.   recs += [(startCol: 123; endCol: 123)];
  14.  {...}
  15. end;
  16.  

Am I missing something or is this record init. syntax reserved for only some ocassions?
i use arch btw

ASerge

  • Hero Member
  • *****
  • Posts: 2475
Re: append new record to array using array operators
« Reply #1 on: December 06, 2025, 08:22:57 am »
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$IFDEF WINDOWS}
  3.   {$APPTYPE CONSOLE}
  4. {$ENDIF}
  5.  
  6. type
  7.   TSomeRecord = record
  8.     StartCol, EndCol: SizeInt;
  9.   end;
  10.  
  11.   TSomeRecords = array of TSomeRecord;
  12.  
  13. procedure SomeProc;
  14. const
  15.   CRec1: TSomeRecord = (StartCol: 123; EndCol: 123);
  16.   CRec2: TSomeRecord = (StartCol: 456; EndCol: 456);
  17. var
  18.   Recs: TSomeRecords;
  19.   R: TSomeRecord;
  20. begin
  21.   Recs := [CRec2, CRec1];
  22.   Insert(CRec2, Recs, 2);
  23.   for R in Recs do
  24.     Writeln('StartCol: ', R.StartCol, ', EndCol: ', R.EndCol);
  25. end;
  26.  
  27. begin
  28.   SomeProc;
  29.   Readln;
  30. end.

speter

  • Sr. Member
  • ****
  • Posts: 486
Re: append new record to array using array operators
« Reply #2 on: December 06, 2025, 08:24:28 am »
have a look at:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$modeswitch advancedrecords}
  5.  
  6. interface
  7.  
  8. uses
  9.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  10.  
  11. type
  12.   TFoo = record
  13.     a, b: Integer;
  14.     constructor Create(aa, bb: Integer);
  15.     procedure list;
  16.   end;
  17.  
  18.   TFooArray = array of TFoo;
  19.  
  20.   { TForm1 }
  21.  
  22.   TForm1 = class(TForm)
  23.     Button1: TButton;
  24.     Memo1: TMemo;
  25.     Panel_bottom: TPanel;
  26.     procedure Button1Click(Sender: TObject);
  27.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  28.     procedure FormCreate(Sender: TObject);
  29.   private
  30.  
  31.   public
  32.     foo: TFooArray;
  33.  
  34.   end;
  35.  
  36. var
  37.   Form1: TForm1;
  38.  
  39. implementation
  40.  
  41. {$R *.lfm}
  42.  
  43. operator + (const Arr: TFooArray; const Item: TFoo): TFooArray;
  44. var
  45.   Len: Integer;
  46. begin
  47.   Result := Arr;                  // Copy existing array
  48.   Len := Length(Result);
  49.   SetLength(Result, Len + 1);     // Resize (this can be expensive)
  50.   Result[Len] := Item;            // Set the new item
  51. end;
  52.  
  53. constructor TFoo.Create(aa, bb: Integer);
  54. begin
  55.   a := aa;
  56.   b := bb;
  57. end;
  58. procedure tfoo.list;
  59. begin
  60.   form1.memo1.append(format('a=%d; b=%d',[a,b]));
  61. end;
  62.  
  63. { TForm1 }
  64.  
  65. procedure TForm1.FormCreate(Sender: TObject);
  66. begin
  67.   SetLength(foo, 0);
  68. end;
  69.  
  70. procedure TForm1.Button1Click(Sender: TObject);
  71.  
  72.   function makefoo (aa,bb : integer) : tfoo;
  73.   begin
  74.     result.a := aa;
  75.     result.b := bb;
  76.   end;
  77.  
  78. var
  79.   afoo : tfoo;
  80. begin
  81.   foo += TFoo.Create(1, 2);
  82.   foo += TFoo.Create(3, 4);
  83.   foo += TFoo.Create(5, 6);
  84.  
  85.   foo += makefoo(7,8);
  86.  
  87.   for afoo in foo do
  88.     afoo.list;
  89.  
  90. end;
  91.  
  92. procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  93. begin
  94.   SetLength(foo, 0);
  95. end;
  96.  
  97. end.

Note that this uses Advanced Records; but if you used function makefoo(), you would not need advanced records - though you'd need to replace the list() method. :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

MMarie

  • New Member
  • *
  • Posts: 48
  • Right, lets bodge this pisspot
    • Homepage
Re: append new record to array using array operators
« Reply #3 on: December 06, 2025, 08:34:49 am »
Code: Pascal  [Select][+][-]
  1. {$MODE OBJFPC}
  2. {$IFDEF WINDOWS}
  3.   {$APPTYPE CONSOLE}
  4. {$ENDIF}
  5.  
  6. type
  7.   TSomeRecord = record
  8.     StartCol, EndCol: SizeInt;
  9.   end;
  10.  
  11.   TSomeRecords = array of TSomeRecord;
  12.  
  13. procedure SomeProc;
  14. const
  15.   CRec1: TSomeRecord = (StartCol: 123; EndCol: 123);
  16.   CRec2: TSomeRecord = (StartCol: 456; EndCol: 456);
  17. var
  18.   Recs: TSomeRecords;
  19.   R: TSomeRecord;
  20. begin
  21.   Recs := [CRec2, CRec1];
  22.   Insert(CRec2, Recs, 2);
  23.   for R in Recs do
  24.     Writeln('StartCol: ', R.StartCol, ', EndCol: ', R.EndCol);
  25. end;
  26.  
  27. begin
  28.   SomeProc;
  29.   Readln;
  30. end.

hmm, maybe my example was quite bad. the values for the record to be appended are not constant in my case, I should've been more clear...
i use arch btw

MMarie

  • New Member
  • *
  • Posts: 48
  • Right, lets bodge this pisspot
    • Homepage
Re: append new record to array using array operators
« Reply #4 on: December 06, 2025, 08:37:53 am »
Note that this uses Advanced Records; but if you used function makefoo(), you would not need advanced records - though you'd need to replace the list() method. :)

The makefoo() variant is probably the most appealing and what I'd go with in the future, since (oustide of Lazarus projects) I tend to stick to a more oldschool procedural style :)
But the advanced record version you suggested is definetly going down in my notes for future Lazarus projects ^^
i use arch btw

jcmontherock

  • Sr. Member
  • ****
  • Posts: 336
Re: append new record to array using array operators
« Reply #5 on: December 06, 2025, 12:08:21 pm »
Code: Pascal  [Select][+][-]
  1. SetLength(RecordsArray, Length(RecordsArray) + 1);
  2. RecordsArray[High(RecordsArray)] := DataRecord;
Or:
Code: Pascal  [Select][+][-]
  1. System.Insert(DataRecord, RecordsArray, Length(RecordsArray));
« Last Edit: December 06, 2025, 04:17:26 pm by jcmontherock »
Windows 11 UTF8-64 - Lazarus 4.4-64 - FPC 3.2.2

Warfley

  • Hero Member
  • *****
  • Posts: 2037
Re: append new record to array using array operators
« Reply #6 on: December 06, 2025, 02:28:36 pm »
Well the most simple solution is to create a constructor function and use the built-in array operators (activate through modeswitch):
Code: Pascal  [Select][+][-]
  1. {$ModeSwitch arrayoperators}
  2.  
  3. type
  4.   TFoo = record
  5.     X, Y: Integer;
  6.   end;
  7.  
  8. function Foo(const X, Y: Integer): TFoo; inline;
  9. begin
  10.   Result.X := X;
  11.   Result.Y := Y;
  12. end;
  13.  
  14. var
  15.   arr: Array of TFoo;
  16. begin
  17.   Arr:=[];
  18.   Arr+=[Foo(42, 32)];
  19. end.

This has a few advantages over the examples shown above:
1. By using a normal function instead of a constructor inlining can be performed. Constructors cannot be inlined, so especially if the record is very small, a normal inlined function will perform better
2. The + operator with modeswitch ArrayOperators is overladed for every single array type, so no need to overload your own operators
3. While the + operator only appends lists, there is an optimization that for single elements it's basically reduced to an Insert, meaning that with the same syntax for appending 1 or any number of elements, the compiler automatically decides the optimal way to perform this operation, so no manual optimization necessary.

speter

  • Sr. Member
  • ****
  • Posts: 486
Re: append new record to array using array operators
« Reply #7 on: December 07, 2025, 12:46:02 am »
Well the most simple solution is to create a constructor function and use the built-in array operators...
That is very elegant! :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

PascalDragon

  • Hero Member
  • *****
  • Posts: 6284
  • Compiler Developer
Re: append new record to array using array operators
« Reply #8 on: December 08, 2025, 10:53:41 pm »
Am I missing something or is this record init. syntax reserved for only some ocassions?

Correct, it's only available for constant and variable initialization.

 

TinyPortal © 2005-2018