Rotating keys in a table

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
megalukes
Citizen
Posts: 94
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Rotating keys in a table

Post by megalukes »

Is there a function to rotate keys in Lua? Something like this:

Code: Select all

-- table.rotate(t,value) value accepting positive and negative numbers

table = {1, 2 ,3 ,4 ,5}
table.rotate(table,1) -- {2, 3, 4, 5, 1}

table2 = {1, 2 ,3 ,4 ,5}
table.rotate(table2,-1) -- {5, 1, 2, 3, 4}
I was so used with it in Ruby, but now I think it's awkward there isn't anything similar in Lua (I didn't find it anywhere, somebody must've done, somewhere).
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Rotating keys in a table

Post by raidho36 »

No, there isn't one. Lua tables are much more than simple arrays so it makes no sense to implement something with that narrow use case into core language, which also prides itself on being minimalistic. Depending on your use case, you can simply shift lookup index left or right and wrap it around, or implement such function yourself which is trivial. Note that shifting lookup key is preferable because actually rearranging values inside the table is computationally expensive by comparison.
User avatar
ivan
Party member
Posts: 1912
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Rotating keys in a table

Post by ivan »

Shifting by 1 in either direction is easy by using table.insert/remove, for example:

Code: Select all

-- left right by 1
t = {1, 2 ,3 ,4 ,5}
local last = table.remove(t)
table.insert(t, 1, last) -- {5, 1, 2, 3, 4 }
Note that your code overwrites the 'table' global so we have to be careful with that.
Unfortunately, shifting by more than 1 element becomes a pain and it's not super efficient.
Like Raidho said, the important question is: is there any good reason to shift all that data around?
An easier way would be write a special function for accessing shifted tables:

Code: Select all

t = {1, 2 ,3 ,4 ,5}

function get_value_by_shift(t, index, shift)
  index = (index + shift - 1)%#t + 1
  return t[index]
end
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Rotating keys in a table

Post by raidho36 »

Not particularly efficient but that will do the business.

Code: Select all

function table.rotate ( t, num )
	for i = 1, math.abs ( num ) do
		if num < 0 then
			table.insert ( t, 1, table.remove ( t ) )
		else
			table.insert ( t, table.remove ( t, 1 ) )
		end
	end
end
Paste this anywhere (actually atop) in your code and you'll be able to use it just as in your mock code in OP.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Rotating keys in a table

Post by airstruck »

Not much trouble if you don't need to do it in place.

Code: Select all

local function rotate (t, n)
    local len, out = #t, {}
    for i = 1, len do out[i] = t[1 + (i - 1 + n) % len] end
    return out
end
Writing a special shifted accessing function does sound like a good solution, though.
User avatar
megalukes
Citizen
Posts: 94
Joined: Fri Jun 27, 2014 11:29 pm
Location: Brazil

Re: Rotating keys in a table

Post by megalukes »

Thank you everyone for the tips and snippets. :awesome: :awesome: :awesome:
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 3 guests