2

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
}
3
  • 2
    See table.move. Commented May 3, 2022 at 17:08
  • What you want to achieve is not shifting, it's called rotating. Commented May 3, 2022 at 19:32
  • I've made table.insert(connections, 1, table.remove(connections)) and was not sure that it was a good solution Commented May 3, 2022 at 19:44

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

For Lua 5.3+, you can use table.move to do most of the work:

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

1 Comment

How to shift not to hardcoded one? For example 2 or -1.
0

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

But the version of LMD is simpler and can accept left shifting too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.