[Done] Table Help

Place to get help with not working mods / modding interface.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

[Done] Table Help

Post by TheSAguy »

Hi,

I have a table that contains some positions.
At certain stages, I'd like to go through this table and delete entries, where the tile at the position is not "Pheromone Concrete"

The problem I'm having is that I can't use:

Code: Select all

for i = 1, #global.laid_pheromone_concrete do
because if I delete an entry, "i" loses it's integrity.
So how would I handle this?

Here is my current code:

Code: Select all

	if game.tick % (60 * 60 * 1) == 0 then
	

		if #global.laid_pheromone_concrete > 0 then
			
			local New_tiles = {}
			local Tile_test = false			
			
		for i = 1, #global.laid_pheromone_concrete do
	
				local surface = global.laid_pheromone_concrete[i].surface
				local currentTilename = surface.get_tile(global.laid_pheromone_concrete[i].position).name
				
				
				if currentTilename == "pheromone_concrete" then

					local Tile_test = true	
					table.insert(New_tiles, {name="exhausted_pheromone_concrete", position=global.laid_pheromone_concrete[i].position}) 
					surface.set_tiles(New_tiles)
					
				else
					writeDebug("Not Pheromone Concrete, so remove from table...")	
					table.remove(global.laid_pheromone_concrete, i) -- This breaks i
				end
				
			end
		end
	end



This is where I populate the table, don't think it's relevant here:

Code: Select all

----- Pheromone Concrete stuff
--------------------------------------------------------------------
local function pheromone_concrete_laid (event, surface)

	for i, vv in ipairs(event.tiles) do
		local position = vv.position
		local currentTilename = surface.get_tile(position.x,position.y).name
		
		if currentTilename == "pheromone_concrete" then
						
			if not global.laid_pheromone_concrete then global.laid_pheromone_concrete = {} end
			local pheromone_time = 5000 --math.random(5000) + 5000
			table.insert(global.laid_pheromone_concrete, {position = vv.position, time = event.tick + pheromone_time, surface = surface})
			table.sort(global.laid_pheromone_concrete, function(a, b) return a.time < b.time end)			
			
		else	
			writeDebug("Something Else Happened...")			
		end
		
	end	

	
end


local function Player_Tile_Built(event)

	local player = game.players[event.player_index]
	local surface = player and player.surface

	writeDebug("Tile Built")		
	if event.tiles then pheromone_concrete_laid (event, surface) end

	
end

	
local function Robot_Tile_Built(event)


	local robot = event.robot
	local surface = robot.surface
	
	-- fix #2 Error while running event Bio_Industries::on_robot_built_tile
	if surface == nil then
		return
	end
	
	if event.tiles then pheromone_concrete_laid (event, surface) end

end

Last edited by TheSAguy on Wed Apr 24, 2019 2:20 pm, edited 2 times in total.
eduran
Filter Inserter
Filter Inserter
Posts: 344
Joined: Fri May 09, 2014 2:52 pm
Contact:

Re: Table Help

Post by eduran »

Assuming you want to keep your table sorted and indexed in an array-like way:

Code: Select all

local last_element_index = 1

for current_index = 1, #my_table do
  -- add code here to figure out if you want to keep or remove my_table[current_index]
  
  if keep_this_value then    
    if current_index ~= last_element_index then
      my_table[last_element_index] = my_table[current_index]
      my_table[current_index] = nil
    end
    last_element_index = last_element_index + 1
  else
    my_table[current_index] = nil
  end
end
If you don't care about ordering, just traverse the table with pairs and delete elements as you go.
TheSAguy
Smart Inserter
Smart Inserter
Posts: 1456
Joined: Mon Jan 13, 2014 6:17 pm
Contact:

Re: Table Help

Post by TheSAguy »

Thanks Eduran, that did it!
Post Reply

Return to “Modding help”