Lua - Modifying List Elements



We can access the list element while traversing them and as tables are references, the modification done will reflect. In the similar fashion, after accessing the first and last element we can modify them.

We'll build the list and then add method to get first element, last element and to iterate the list and in this process, we'll update and print the values 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: Get first element and then we can modify it.

Create a function to get first element

function list:getFirst()
   -- if first is nil then return
   if not self.first then
      return 
   end
   return self.first
end

Step 4: Get Last element and then we can modify it.

Create a function to get last element

function list:getLast()
   -- if last is nil then return
   if not self.last then
      return 
   end
   return self.last
end

Step 5: Create iterator over list and update complete list during iteration.

Create an iterator to navigate through elements of the list.

-- iterate through the list
local function iterate(self, current)
   -- if current is nil
   -- set the current as first node
   if not current then
      current = self.first
   -- if current is present
   -- set current as current next   
   elseif current then
      current = current._next
   end
   -- return current  
   return current
end

-- return the iterator
function list:iterate()
   return iterate, self, nil
end

Step 6: Test Modification of elements on List

In list, we can insert objects,

-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })

print("Update List to make each entry in Uppercase")
-- iterate throgh entries
for v in l:iterate() do 
   print(string.upper(v[1])) 
end

-- modify first element
l:getFirst()[1] = "MONDAY"
print("First Element: " , l:getFirst()[1])

-- modify last element
l:getLast()[1] = "FRIDAY"
print("Last Element: " , l:getLast()[1])

Complete Example - Modify an element of a List

Following is the complete example of modifying elements of a list.

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

-- iterate through the list
local function iterate(self, current)
   if not current then
      current = self.first
   elseif current then
      current = current._next
   end
  
   return current
end

function list:iterate()
   return iterate, self, nil
end

function list:getLast()
   -- if last is nil then return
   if not self.last then
      return 
   end
   return self.last
end

function list:getFirst()
   -- if first is nil then return
   if not self.first then
      return 
   end
   return self.first
end

-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })

print("Update List to make each entry in Uppercase")
-- iterate throgh entries
for v in l:iterate() do 
   print(string.upper(v[1])) 
end

-- modify first element
l:getFirst()[1] = "MONDAY"
print("First Element: " , l:getFirst()[1])

-- modify last element
l:getLast()[1] = "FRIDAY"
print("Last Element: " , l:getLast()[1])

Output

When we run the above code, we will get the following output−

Update List to make each entry in Uppercase
MON
TUE
WED
THU
FRI
First Element: 	MONDAY
Last Element: 	FRIDAY
Advertisements