循环移动数组

Shift the array as loop

如何循环移动列表? 输入:

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

需要的结果:

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
}

您想使用“环绕式”/“循环式”轮班进行轮班。 [table.move],如 lhf 所指出的,几乎是您所需要的,但缺少“循环部分”并且在 Lua 的旧版本(例如 5.1,仍在广泛使用).因此,我建议在 Lua 中实现它,如下所示,特别是如果你想要一个新的 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

这会为您的示例生成正确的结果:

> 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

谢谢大家,Lua 5.1(和 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)))

结果:

1   1   0   1
1   1   1   0
0   1   1   1
1   0   1   1

但是LMD的版本更简单,也可以接受左移。

对于 Lua 5.3+,您可以使用 table.move 完成大部分工作:

function shift(a)
        local n=#a
        local t=a[n]
        table.move(a,1,n-1,2)
        a[1]=t
end