user3764855
user3764855

Reputation: 297

How to slice a dynamic array?

How can I slice a dynamic array to multiple sub arrays? Slice() function in Delphi does not support dynamic arrays. So how can it be done? A generic solution would be welcome.

program Project10;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  A: Array of Integer;
begin
  SetLength(A, 4);
  Slice(A, 2); // [dcc32 Error] Project10.dpr(15): E2193 Slice standard function only allowed as open array argument
end.

Upvotes: 5

Views: 3267

Answers (2)

Morten Brendefur
Morten Brendefur

Reputation: 112

It is possible to use pointers in order to access a Dynamic Array from different "start points"

Consider the code:

TYPE
  tListArray = ARRAY[0..0] OF CARDINAL; {Or any other type you need}
  tDynamicCardinalArray = ARRAY OF CARDINAL;
VAR
  MyList : tDynamicCardinalArray;
  pArrPos1, pArrPos2 : ^tListArray;
BEGIN
  SetLength(MyList,100);
  pArrPos1 := @MyList[0];
  pArrPos2 := @MyList[50];
  ...
  ...
END;

The benefit is that you have direct access, no copying or moving of data involved. The drawback is that functions such as "high", "low" and "length" CAN NOT be used on these array-pointers. Or at least not if you want a result to use. You have to make sure that you never go beyond the scope of the SourceArray MyList when you address the array-pointers. The benefit is that it brings versatility to Dynamic Arrays. As we know, a Dynamic Array can only be created from 0 .. and up to the size. pArrPos2 on the other side has effectively rendered the Dynamic Array into an Array-Pointer which also accept negative addressing:

pArrPos2^[-50] :=  0; // Equals: MyList[ 0] :=  0
pArrPos2^[  0] := 50; // Equals: MyList[50] := 50
pArrPos2^[ 49] := 99; // Equals: MyList[99] := 99

Using pointers, you can "slice" a Dynamic Array into several pieces, but you have to keep track of the "High", "Low", and "Length" separately, at least if you want a fully dynamic solution that can be changed on the fly in software. The needed extra information can be passed as an extra parameter to a procedure or function and takes less CPU-time than actually copying or moving a dataset into a new array.

I know. the post was old, but I still think my answer would/could be relevant here, in particular for new readers.

Upvotes: 1

Daniel
Daniel

Reputation: 1051

Use Copy(A, 0, 2) instead of Slice(A, 2).

The point is that either you need an "open array parameter" (in which case you need Slice) or you need a regular array, in which case Copy will provide a good solution.

Upvotes: 8

Related Questions