I'm trying to create a function that 'drags' a sequential number of elements to a new location within the array, constrained to the current size of the array. Other items should jiggle round the 'dragged' items.
For example, if my array has 7 elements and I want to drag the middle three...
1, 2, 3, 4, 5, 6, 7 <-- keys
a, b, C, D, E, f, g <-- values
The uppercase chars are the ones I want to 'drag'. If I drag to start of the array (drag to 1) the array would look like this:
1, 2, 3, 4, 5, 6, 7 <-- keys
C, D, E, a, b, f, g <-- values
If I drag to position 5 (or above - can't be dragged outside current array size) the array would look like this:
1, 2, 3, 4, 5, 6, 7 <-- keys
a, b, f, g, C, D, E <-- values
Any idea how I can achieve that using Lua in a non-crufty manner?
Here is a version using table.move
available in Lua 5.3.
It copies the group to be dragged into another table and shifts values up or down to make room for the group.
function drag(t, src, len, dest)
local copy = table.move(t, src, src + len - 1, 1, {})
if src >= dest then
table.move(t, dest, src - 1, dest + len)
else
table.move(t, src + len, dest + len - 1, src)
end
table.move(copy, 1, len, dest, t)
end
function drag(t, src, len, dest)
if len == 0 then return end
local left, ctr, start, index, elem = math.min(src, dest), 0, 0
local rot, size = dest - src, src + dest + len - 2 * left
repeat
start, index, elem = start + 1, start, t[left + start]
repeat
index = (index + rot) % size
ctr, t[left + index], elem = ctr + 1, elem, t[left + index]
until index < start
until ctr == size
end
for K = 1, 5 do
local tbl = {'a', 'b', 'C', 'D', 'E', 'f', 'g'}
drag(tbl, 3, 3, K)
print(table.concat(tbl))
end