Searching Tables

Hello everyone - I have another table question,

Lets say I have a function that creates a new person, and also randomly places them on a floor between 1 and3, like such:

  
local function addperson()  
 local i = math.random (3)  
   
 local person = display.newImage("person.PNG")  
 persontable[#persontable+1] = person  
   
 person.floor = i  
  
end  
  

I would like to have a function that searches persontable to see if there is anyone on floor 3. I would only like to search the table once, and run the function once regardless of whether there are 1 persons on floor 3 or 100.

Something like:

[code]
– a function to see if there is a person on floor 3
local function searchFloorthree()
If persontable[i].floor = 3 then
print (“yes, there is at least one person on that floor”
end
end

[code]

help is very much appreciated!!

[import]uid: 78150 topic_id: 21829 reply_id: 321829[/import]

Something like ?

[code]

local peopleOnFloor = 0

for i = 1, #persontable do
if persontable[i].floor == 3 then
peopleOnFloor = peopleOnFloor + 1
end
end

print(peopleOnFloor) [import]uid: 84637 topic_id: 21829 reply_id: 86722[/import]

for the general case of N floors I would recommend just using a different bucket (table) for each floor. Something like this:

local persontables = { {}, {}, {} } --for 3 floors  
  
local function addPerson()  
 local i = math.random ( 3 )  
   
 local person = display.newImage( "person.PNG" )  
 persontables[i][#persontables[i]+1] = person  
 person.floor = i  
end  
  
local function isAnyoneOnFloor( i )  
 return #persontables[i] \> 0  
end  
  

If you really have only 3 floors you can use this smart trick:

local idx1 = 1 --index to the place where we should put 2nd floor persons  
local persontable = {}  
  
local function addPerson()  
 local i = math.random( 3 )  
 local person = display.newImage( "person.PNG" )  
 person.floor = i  
  
 if i == 1 then  
 table.insert( persontable, 1, person )  
 idx1 = idx1 + 1  
 elseif i == 2 then  
 table.insert( persontable, idx1, person )  
 else -- i must be 3  
 persontable[#persontable+1] = person  
 end  
end  
  
local function isAnyoneOnFloor( i )  
 if #persontable \> 0 then  
 if i == 1 and persontable[1].floor == 1 then  
 return true  
 elseif i == 2 and persontable[idx1].floor == 2 then  
 return true  
 elseif i == 3 and persontable[#persontable].floor == 3 then  
 return true  
 end  
 end  
 return false  
end  

The trick here is that because you only have 3 floor values you can push the persons with floor 1 at the beginning, the ones with floor 3 at the end and just keep floor 2 persons in between. This will keep your table sorted by floor as you insert person tables. You have the ‘idx1’ for keeping where to insert the next 2nd floor person (always points to the first person after the last 1st floor person).
The nice thing here is that you do not need to traverse the table at all in order to get what you need.

An even simpler approach would be to insert anything with floor~=3 at the start and those with floor 3 at the end, that’s if you only care about the 3rd floor occupancy. Then just check the last element in the table to see if it’s on floor 3.

Using one of these solutions would eliminate the need to loop through the persontable which could be expensive if you get to a large number of people and lets say need to do this on enterFrame…
It also makes it quite easy to delete persons and keeping the container sorted and easily maintained.

If you have more than 3 floors and do not want to change the data container structure you can implement a binary search on the table, like this. You just need to adjust it to search by the .floor attribute and not the value itself, but it’s not my recommendation :slight_smile:
PS, consider the code above pseudo code as I never ran it anywhere :slight_smile: [import]uid: 80469 topic_id: 21829 reply_id: 86723[/import]

excellent responses as always =) [import]uid: 78150 topic_id: 21829 reply_id: 86729[/import]