Home > other >  Shift the array as loop
Shift the array as loop

Time:05-04

How can I shift the list as a loop? The input:

local connections = {1, 1, 0, 1}

Needed result:

local variants = {
    {1, 1, 0, 1}, -- as original table
    {1, 1, 1, 0}, -- shifted once to the right
    {0, 1, 1, 1}, -- shifted twice
    {1, 0, 1, 1}, -- shifted three times
}

CodePudding user response:

You want to perform a shift with "wraparound" / "circular" shift. [table.move], as pointed out by lhf, is almost what you need, but lacks the "circular part" and is unavailable on older versions of Lua (such as 5.1, which is still in widespread use). I thus propose implementing this in Lua as below, particularly if you want a new table:

local function cyclic_table_shift(tab, shift)
    local len = #tab
    local shifted = {}
    for i = 1, len do
        shifted[i] = tab[(i - 1 - shift) % len   1] -- mod to make it wrap
    end
    return shifted
end

this yields the correct results for your example:

> connections = {1, 1, 0, 1}
> function cyclic_table_shift(tab, shift)
>>     local len = #tab
>>     local shifted = {}
>>     for i = 1, len do
>>         shifted[i] = tab[(i - 1 - shift) % len   1] -- mod to make it wrap
>>     end
>>     return shifted
>> end
> table.unpack(cyclic_table_shift(connections, 0))
1   1   0   1
> table.unpack(cyclic_table_shift(connections, 1))
1   1   1   0
> table.unpack(cyclic_table_shift(connections, 2))
0   1   1   1
> table.unpack(cyclic_table_shift(connections, 3))
1   0   1   1

CodePudding user response:

Thanks all, there is the solution for Lua 5.1 (and 5.4)

if not table.move then
    print ('used custom table.move')
    -- thanks to index five
    function table.move(a1,f,e,t,a2) -- a1, f, e, t [,a2]
    --  Moves elements from the table a1 to the table a2, 
    --  performing the equivalent to the following multiple assignment: 
    --  a2[t],··· = a1[f],···,a1[e]. The default for a2 is a1. 
    --  The destination range can overlap with the source range. 
    --  The number of elements to be moved must fit in a Lua integer.
        a2 = a2 or a1
        if (a2 ~= a1) or (t < f) then -- use a2
            for i = f, e do 
                a2[t i-f] = a1[i] 
            end
        elseif (t > f) then
            for i = e, f, -1 do 
                a2[t i-f] = a1[i] 
            end
        end
        return a2
    end
end

table.unpack = table.unpack or unpack

function circularShift (tabl, shift)
    local len = #tabl
    local shifted = {}
    table.move(tabl,len-shift,len,0,shifted)
    table.move(tabl,1,len-shift,shift 1,shifted)
    return shifted
end

local connections = {1, 1, 0, 1}

print (table.unpack(circularShift(connections, 0)))
print (table.unpack(circularShift(connections, 1)))
print (table.unpack(circularShift(connections, 2)))
print (table.unpack(circularShift(connections, 3)))

Result:

1   1   0   1
1   1   1   0
0   1   1   1
1   0   1   1
  • Related