Lua - Searching in Lists
In order to search a list, we need to traverse and check if given element is present or not. To check an element in a list, we'll be using two approaches.
Create Iterator and search element using for loop
Navigate the list using while loop and search element.
Using iterator
Let's build an iterator which can return the next element of the list to do the traversing and check the element in for loop. See the following code of the iterator function on 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:iterator()
return iterate, self, nil
end
We can use list:iterator() function to iterate the list which will return the next element when invoked in a for loop as shown below:
itemToSearch = "wed"
found = false
-- iterate throgh entries
for v in l:iterator() do
if v[1] == itemToSearch then
found = true
break
end
end
if found then
print(itemToSearch, "is present in the list.")
else
print(itemToSearch, "not present")
end
Complete Example - Searching an element of a List using iterator and for loop
Following is the complete example of inserting and searching 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:iterator()
return iterate, self, nil
end
-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })
itemToSearch = "Wed"
found = false
-- iterate throgh entries
for v in l:iterator() do
if v[1] == itemToSearch then
found = true
break
end
end
if found then
print(itemToSearch, "is present in the list.")
else
print(itemToSearch, "not present.")
end
itemToSearch = "Sat"
found = false
-- iterate throgh entries
for v in l:iterator() do
if v[1] == itemToSearch then
found = true
break
end
end
if found then
print(itemToSearch, "is present in the list.")
else
print(itemToSearch, "not present")
end
Output
When we run the above code, we will get the following output−
Wed is present in the list. Sat not present.
Using While Loop
We can navigate through the list using while loop and return true if element found else return true.
-- search an element in list,
-- returns true if found else returns false
function list:search(value)
found = false
-- set current as first node
current = self.first
-- navigate till end of the list
while current._next do
-- if element found
if current[1] == value then
found = true
break
end
-- point to next node
current = current._next
end
return found
end
We can pass an item to search in this method and return true/false based on item's availablilty in the list.
Complete Example - Searching an element of a List using while loop
Following is the complete example of inserting and searching 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
-- search an element in list,
-- returns true if found else returns false
function list:search(value)
found = false
-- set current as first node
current = self.first
-- navigate till end of the list
while current._next do
-- if element found
if current[1] == value then
found = true
break
end
-- point to next node
current = current._next
end
return found
end
-- create a new list with values
local l = list({ "Mon" }, { "Tue" }, { "Wed" }, { "Thu" }, { "Fri" })
itemToSearch = "Wed"
found = l:search(itemToSearch)
if found then
print(itemToSearch, "is present in the list.")
else
print(itemToSearch, "not present.")
end
itemToSearch = "Sat"
found = l:search(itemToSearch)
if found then
print(itemToSearch, "is present in the list.")
else
print(itemToSearch, "not present.")
end
Output
When we run the above code, we will get the following output −
Wed is present in the list. Sat not present.