Lua - List length
List is a dynamic data structure and in order to keep track of size of the list, we can keep a length as state of the list. We can increment the length by 1 whenever an element is added to the list and decrement it by 1 when an element is removed.
We'll build the list and then add method to insert an element, remove an element and get size of the list.
Step 1: Create List
Create a List with a push method to add an element to the end of the list.
-- List Implementation
list = {}
list.__index = list
-- push an element to the end of the list
function list:push(t)
-- move till last node
if self.last then
self.last._next = t
t._prev = self.last
self.last = t
else
-- set the node as first node
self.first = t
self.last = t
end
-- increment the length of the list
self.length = self.length + 1
end
Step 2: Using setmetatable
modify list behavior when list is called to push elements.
setmetatable(list, { __call = function(_, ...)
local t = setmetatable({ length = 0 }, list)
for _, v in ipairs{...}
do t:push(v)
end
return t
end })
Step 3: Create remove() method
Create remove(t) to remove a given element.
-- remove a specific element, t
function list:remove(t)
-- if node to delete has next node
-- update the pointers of prev and next nodes
if t._next then
if t._prev then
t._next._prev = t._prev
t._prev._next = t._next
else
-- this was the first node
t._next._prev = nil
self._first = t._next
end
elseif t._prev then -- if node has prev node only
-- this was the last node
t._prev._next = nil
self._last = t._prev
else
-- this was the only node
self._first = nil
self._last = nil
end
t._next = nil
t._prev = nil
self.length = self.length - 1
end
Step 4: Get Length of the List
Create a function to get length of the list
function list:size() return self.length end
Step 5: Test Length of the List
In list, insert and remove object and check the length of the list
-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })
print("Original List Size:", l:size())
-- remove an element
l:remove({"Wed"})
print("List Size after removing one element:", l:size())
-- add an Element
l:push({"Sat"})
print("List Size after adding one element:", l:size())
Complete Example - Size of a List
Following is the complete example of checking size of a list after adding/removing element.
main.lua
-- List Implementation
list = {}
list.__index = list
setmetatable(list, { __call = function(_, ...)
local t = setmetatable({ length = 0 }, list)
for _, v in ipairs{...}
do t:push(v)
end
return t
end })
-- push an element to the end of the list
function list:push(t)
-- move till last node
if self.last then
self.last._next = t
t._prev = self.last
self.last = t
else
-- set the node as first node
self.first = t
self.last = t
end
-- increment the length of the list
self.length = self.length + 1
end
-- remove a specific element, t
function list:remove(t)
-- if node to delete has next node
-- update the pointers of prev and next nodes
if t._next then
if t._prev then
t._next._prev = t._prev
t._prev._next = t._next
else
-- this was the first node
t._next._prev = nil
self._first = t._next
end
elseif t._prev then -- if node has prev node only
-- this was the last node
t._prev._next = nil
self._last = t._prev
else
-- this was the only node
self._first = nil
self._last = nil
end
t._next = nil
t._prev = nil
self.length = self.length - 1
end
function list:size()
return self.length
end
-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })
print("Original List Size:", l:size())
-- remove an element
l:remove({"Wed"})
print("List Size after removing one element:", l:size())
-- add an Element
l:push({"Sat"})
print("List Size after adding one element:", l:size())
Output
When we run the above code, we will get the following output−
Original List Size: 5 List Size after removing one element: 4 List Size after adding one element: 5