Stumbling across this one while facing a similar issue.
I have not implemented it yet, but have thought about this different approach: KEEP the array as it is, but make a new procedure to read values where you change the "zero" position.
Example:
read_array(index: integer; shift: integer)..
So if your original array is read with this function, using shift "1" it would read "1,2,3,4,0" (obviously looping). It would require you to keep track of a few things, but would not require modifying anything. So performance should be greater for very large arrays.
Similar would work for other types as well.
EDIT: an example function with free start index and variable step size plus sample size is here:
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;
Thereby:
get_shifted_array(
inputarray,
-1, // shiftindex
length(inputarray),
1 ) // stepsize
would return the array shifted backwards one place.
All without any modification to array.