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

Is there a way to combine "for" loops?

I have a script in my game that selects all the parts of 10 models and changes their transparency. Problem is, the script is pretty long when using 10 for loops for every model. And no, I can't combine all the parts into 1 model, because it would ruin other scripts I have for my game. Simply, I want to know if there's a way to turn this type of code:

local model1 = game.Workspace.model1:GetChildren()
for i = 1, #model1 do
	model1[i].Transparency = 1
end

local model2 = game.Workspace.model2:GetChildren()
for i = 1, #model2 do
	model2[i].Transparency = 1
end

local model3 = game.Workspace.model3:GetChildren()
for i = 1, #model3 do
	model3[i].Transparency = 1
end

--etc

into something with maybe 5 lines.

2 answers

✓ Accepted answer

I'm quite unsure about combining "for" loops except to tell you to nest them together and put the model variables in a table like so:


model1 = game.Workspace.model1:GetChildren()

model2 = game.Workspace.model2:GetChildren()

model3 = game.Workspace.model3:GetChildren()

MODELtable = {model1, model2, model3}

for i = 1, #MODELtable do
	for i2 = 1, #MODELtable[i] do
		MODELtable[i][i2].Transparency = 1
	end
end

But you could also combine tables with a function instead.

totalmodel = {}			-- Initialized the total children of all models, which has a length of 0.

model1 = game.Workspace.model1:GetChildren()

model2 = game.Workspace.model2:GetChildren()

model3 = game.Workspace.model3:GetChildren()

function tableinsert(TABLE)		-- TABLE is the argument for efficiency.
	for i = 1, #TABLE do
		table.insert(totalmodel, (#totalmodel + 1), TABLE[i])	-- Adds the elements in the totalmodel table.
	end
end

tableinsert(model1)

tableinsert(model2)

tableinsert(model3)

for i = 1, #totalmodel do
	totalmodel[i].Transparency = 1
end

-- Both code tested and works.

Check back with me if you have any questions.

6 comments

1

Thanks. I am kind of new to tables, and this is a bit confusing for me. When you have a line saying "tableinsert(model1)," the (model1) turns into the table used in the function, correct? Also, what does the (totalmodel + 1) do?

1

Yes, the items in "model1" will be used to insert in the "totalmodel" table.

1

Just tested this and it works. Thanks!

1

The (#totalmodel + 1) operation adds the items in the table so that it wouldn't overwrite with the first index. For example, the length of table "totalmodel" in line 1 is 0, as there are 0 items in there. I must add 1, elsewise the first index of the model table will be 0.

0

You're welcome. :D

0

Ok, thanks a lot.

For your particular code, we can see that we're just repeating the same code, so it might just make more sense to make a function:

function hide(model)
	for _, part in pairs(model:GetChildren()) do
		part.Transparency = 1
	end
end

hide(game.Workspace.model1)
hide(game.Workspace.model2)
hide(game.Workspace.model3)

I use a generic for loop instead to be a bit cleaner -- you avoid having to say model[i], which I think makes it much easier to read / understand.

If you have a bunch of these models to do this to, it's now easy to make that into a loop:

for _, mod in pairs(workspace.Hidden:GetChildren()) do
	hide(mod)
end

Here's a stranger way to do it, that turns out to be the same (just for fun)

m1 = workspace.model1:GetChildren()
m2 = workspace.model2:GetChildren()
m3 = workspace.model3:GetChildren()

for i = 1, #m1 + #m2 + #m3 do
	local which
	if i <= #m1 then
		which = m1
	else
		i = i - #m1
		if i <= #m2 then
			which = m2
		else
			i = i - #m2
			which = m3
		end
	end
	local part = which[i]
	part.Transparency = 1
end

This is for the particular case of 3 models. It basically jams the three lists next to each other, so that once one list ends, the next begins at the next index.

This is a mess to do, so let's not do that. If we make it more general, it actually cleans up:

local ms = {m1, m2, m3}

local total = 0
for _, m in pairs(ms) do
	total = total + #m
end

for i = 1, total do
	local which = 1
	while i > #ms[which] do
		i = i - #ms[which]
		which = which + 1
	end
	ms[which][i].Transparency = 1
end

This still isn't very clean. The reason is clear in the last line; our outer loop uses i but the first thing we care about is which, so we should just flip them:

for which = 1, #ms do
	for i = 1, #ms[which] do
		ms[which][i].Transparency = 1
	end
end

which, which generic for loops, looks much neater:

for _, m in pairs(ms) do
	for _, part in pairs(m) do
		part.Transparency = 1
	end
end

(Which is the straightforward top solution)

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