Notification texts go here Contact Us Buy Now!

How to shift data in array?

Shifting Data in an Array

Custom Procedure


procedure ShiftArrayLeft(var arr: array of Integer);
var
  i: Integer;      
  tmp: Integer;
begin
  if Length(arr) < 2 then
    exit;

  tmp := arr[0];
  for i := 0 to high(arr) - 1 do
    arr[i] := arr[i + 1];
  arr[high(arr)] := tmp;
end;

Generic Method for Modern Delphi


Type
  TMyArray = record
    class procedure RotateLeft<T>(var a: TArray<T>); static;
  end;

class procedure TMyArray.RotateLeft<T>(var a: TArray<T>);
var
  tmp : T;
  i : Integer;
begin
  if Length(a) > 1 then begin
    tmp := a[0];
    for i := 1 to High(a) do
      a[i-1] := a[i];
    a[High(a)] := tmp;
  end;
end;

Low-Level Routine Using Move


class procedure TMyArray.RotateLeft<T>(var a: TArray<T>);
var
  tmp : T;
begin
  if Length(a) > 1 then begin
    Move(a[0],tmp,SizeOf(T));          // Temporary store the first element
    Move(a[1],a[0],High(a)*SizeOf(T));
    Move(tmp,a[High(a)],SizeOf(T));    // Put first element last
    // Clear tmp to avoid ref count drop when tmp goes out of scope
    FillChar(tmp,SizeOf(T),#0);
  end;
end;

Alternative Approach

Consider keeping the array as it is and creating a function to read values with a shifted starting index. This eliminates the need for array modification, potentially improving performance for large arrays. Example function:

function get_shifted_array(inArray: TStringList; startindex,
  lineCount: integer;
  stepsize: integer): TStringList;

var
   i : integer;           // temp counter
   nextindex : integer;   // calculate where to get next value from...
   arraypos  : integer;   // position in inarray to take
   temp      : tstringlist;


        // function to mimic excel Remainder( A,B) function
        // in this   remainder(-2,10) = 8
        //
           function modPositive( dividend, divisor: integer): integer;
           var
              temp : integer;

            begin

               if dividend < 0 then
                   begin
                       temp := abs(dividend) mod divisor;   // 1 mod 10 =9    for -1
                                                            // 122 mod 10 = 2  for -122
                       result :=  (divisor - temp);
                   end
               else
                  result := dividend mod divisor;
            end;


begin

   nextindex := startindex;             // where in input array to get info from
   temp := tstringlist.create;          // output placeholder

   for i := 1 to lineCount do
      begin

          // convert to actual index inside loop
          arraypos := modPositive(nextindex, inarray.count);     // handle it like Excel: remainder(-1,10) = 9

          // if mod is zero, we get array.count back. Need zero index then.
          if arraypos = inArray.Count then arraypos := 0;        // for negative loops.

          // get the value at array position
          temp.Add( 'IDX=' + inttostr(arraypos) + ' V=' +   inarray[  arraypos ] );

          // where to go next
          // should we loop ?
          if ((nextindex+ stepsize +1)> inArray.Count ) then
                 begin
                     nextindex :=  (nextindex + stepsize ) mod inArray.Count;
                 end
          else
              nextindex := nextindex + stepsize;
      end;

   result := temp;

end;

Fast Array Rotation Function with Transient Memory Overhead


function RotateArray(list:Tintarray; x:integer):Tintarray;
var n:integer;
begin
  n:=length(list);
  x:=x mod n;
  if (n<2) or (x=0) then
    result:=Copy(list)
  else
  if x>0 then
    result:=Copy(list,n-x,x) + Copy(list,0,n-x)
  else
    result:=Copy(list,-x,n-x) + Copy(list,0,-x)
end;

Post a Comment

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.