Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

What is an alternative to using in pairs on top of in pairs?

Hello, in short, my real problem is that I'm at that level of scripting where you know how to do something, but only one way.

for i, link in pairs(links) do
	if link.Switches ~= nil then
		link.CancelledLinks = {}
		for j, switch in pairs(link.Switches) do
			for m, otherLink in pairs(links) do
				if otherLink ~= link and otherLink.Switches ~= nil then
					for b, otherSwitch in pairs(otherLink.Switches) do
						if otherSwitch == switch then
							table.insert(link.CancelledLinks, otherLink)
						end
					end
				end
			end
		end
	end
end

The purpose of this massively-layered loop is to determine what other values of the same table are "cancelled out" by each value. It does this by seeing if they have the one or some of the same switches in their "Switches" table. (This is for train tracks if you're curious.) What would you do instead of this messy code?

6 comments

0

Have one huge table perhaps?

0

ur table must be deeper than mattscys philosophical mind

0

An alternative to using "in pairs on top of in pairs" would be using "in ipairs on top of ipairs."

0

that makes sense, since the links table has numeric indices. Changed it, but there aren't fewer lines

0

Sometimes you just end up with a lot of nested for loops. Looking at that gives me a headache, but if... jesus that's a lot... anyways, adding another table may help a bit, but I seriously don't understand the whole thing. I reccomend using comments to make it easier to read.

0

I recommend using a table with indices that represent what link the link is. That way, when you loop through all of the links, you can quickly index a table to see if a link is nil or not. I don't quite understand what is going on in this script, but I do know that a good solution would be a table with representative indices.

1 answer

✓ Accepted answer

Alright that's some dense data, so let me see if I got this right

You loop through a table of tables, called links In each table you have another table, called switches, which reference other switches potentially in other links You want to find what links have switches that are in any other link

If I wanted to simplify this, I'd use the fact that tables store two sets of data for each entry, an index and a value. Use the index with some unique ID, and you can cut out the innermost otherlink otherswitch loop. Insteading checking if the otherSwitch[uniqueID] isn't nil.

Another trick to making this a lot more reasonable to understand if good ol whitespace, and flipping conditionals so you don't get too far into indents.

Replace if (condition) then do thing end with if (not condition) then break end, one line, doesn't shift the indentation of the rest of the code

for i, link in pairs(links) do
  if link.Switches == nil then break end
  link.CancelledLinks = {}
  for j, switch in pairs(link.Switches) do

    for m, otherLink in pairs(links) do
      if otherLink == link or otherLink.Switches == nil then break end
      if otherLink.Switches[j] then
        table.insert(link.CancelledLinks, otherLink)
      end
    end

  end
end

Honestly it seems like a problem that could use a refactoring to me, I don't know how much simpler you can make it with that structure. I've never tried to do signaling, but it might help to look at some other games (Factorio comes to mind) and try to intuit how they handle it with the tools they give the player, instead of starting from scratch.

1 comment

0

Nothing seems to be wrong with that method. Thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.