Help understanding if statement

I saw another devforum post where someone asked “How do you click through values of a table” and I’m currently trying to do the same thing so I used this code and it worked but I don’t understand it. How does this work? Specifically the (start >= #difficulties and 1)

local start = 1
selecteddifficulty.Activated:Connect(function()
	start = (start >= #difficulties and 1) or start + 1
	local difficulty = difficulties[start]
	selecteddifficulty.Text = 'SELECTED DIFFICULTY: ' .. difficulty
end)
(start >= #difficulties and 1) or start + 1

The or statement doesn’t actually return just a true or false value. It can return a number, a string, an Instance, etc…

The left of the or statement is checked first. If the value returned is false or nil, it checks the right side, and returns that value instead.

Therefore, if start >= #difficulties and 1 is false, it returns start + 1.

1 Like

This is actually called a conditional expression. x and y or z works in similar fashion to ternary operators:

Looking at the modified truth table from x and y or z:

x output
false z
true y

In basic semantics, the right-side of the compound(z) is always the default value if x is false. If the condition is fulfilled, the value becomes y.

1 Like

Modern luau supports a more preferred syntax for writing this logic with an in-line if that is easier to understand:

start = if start >= #difficulties then 1 else start + 1

These statements are mostly equivalent, with one nuance that, unlike c and a or b, the in-line if syntax will correctly handle the case where the first value evaluates to false.

For example, if condition c is truthy, you expect it to return the first variable a in this case:
x = c and a or b
But if a is falsey, it would return the second variable b anyway.

To demonstrate,
Let’s say c = true, a = false, b = true
x = c and a or b returns true (b) instead of false (a)
x = if c then a else b would return false (a) as expected

More generally, here’s a table to compare

c a b c and a or b if c then a else b
false false false b (false) b (false)
false false true b (true) b (true)
false true false b (false) b (false)
false true true b (true) b (true)
true false false b (false) [anomaly] a (false)
true false true b (true) [anomaly] a (false)
true true false a (true) a (true)
true true true a (true) a (true)
As for the whole function, you could break this into explainer variables to help bring clarity, too. This might be a little "extra", but it's unmistakably easy to understand. (expand for code)
local START_INDEX = 1

local Difficulty = {
	"Easy",
	"Medium",
	"Hard"
}

local lastIndex = START_INDEX

local selectDifficultyButton = some.path.to.selectDifficultyButton

selectDifficultyButton.Activated:Connect(function()
	local nextIndex = lastIndex + 1
	
	-- If the next index would be out of bounds, reset to the start index
	local reachedEndOfArray = nextIndex > #Difficulty
	if reachedEndOfArray then
		nextIndex = START_INDEX
	end

	-- Get the difficulty at the new index
	local selectedDifficulty = Difficulty[nextIndex]

	-- Update the button's text to reflect the new difficulty
	selectDifficultyButton.Text = `SELECTED DIFFICULTY: {selectedDifficulty}`
	
	-- Update the last index to the new index
	lastIndex = nextIndex
end)
2 Likes
start = (start >= #difficulties and 1) or start + 1

using # before a table value returns the number of its children
using and/or will work smt like this

local a = 0
local a = (true and 5) -- will be 5
local a = (true and 5) or 1 -- will be 5
local a = (false and 5) or 1 -- will be 1
local a = (false and 5) -- will be false

what happend is that (and) checks if the first value is true if its true then it will return the value after it aka 5
but if the first value is false then it will return false | but if u added an or after it then it will check if it returned false if so then it will return the value after it aka 1


start = 1

start = (start >= #difficulties and 1) or start + 1

so lets break this down
first he checks if start is bigger than the number of children of the table difficulties and if it is then start will be 1
and if itsnot bigger than #difficulties then it will be incremented by 1 | (start + 1)

its the same as

if start >= #difficulties then
	start = 1
else
	start += 1
end

and the first examble is slightly faster than the 2nd one bc its logical operation not conditional statment but the difference is very very small + the first one is more readable

1 Like

Thank you everyone for clearing up my confusion

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.