Neatest way to check if a player has multiple values

Hello there!

I have been working on a certain system that requires the function to check the player if they have multiple variables.

And, I have this placebo code showing my current way of doing so:

local Player = game.Players.LocalPlayer

if Player:FindFirstChild("Value1") and Player:FindFirstChild("Value2") and Player:FindFirstChild("Value3") then
     print("Values found")
end

However, this is very chaotic and can get very inconvenient the more I add.

I’d like to know the best way I could organize this, so it isn’t so chaotic?

Thank you!

1 Like

You can use for loops, less time.

for i, v pairs(Player:GetChildren()) do
   if v.Name == "Value"..i then
      print(v.Name.." Found")
   end
end
2 Likes

I should probably specify that my values aren’t actually named “Value1/2/3.” However, this is really helpful as well for the case scenario when I have numbered values, but not exactly what I’m looking for. Thank you though!

1 Like

If the values have unique names, then what you did in the if statement is perfectly fine. It just looks bigger, doesn’t mean it isn’t efficient.

Another thing you can do is add all of the values you want to check for to a table and run a for loop through it.

Pseudocode:

local table = {"Value1","Value2","Value3"}

function valueChecker()
     for values in table do
          if value not in player
               return value not found
     end
     return all values found
end
2 Likes

It’s fine as it is, but if you’re doing it a lot then here’s a function that abstracts it away.

function hasAllChildren(parent, ...)
    local childNames = {...}
    for _, childName in pairs(childNames) do
        if not parent:FindFirstChild(childName) then
            return false
        end
    end
    return true
end

which you can use like so:

if hasAllChildren(Player, "Value1", "Value2", "Value3") then
    print("Got'em")
else
    print("Got'em'nt")
end
3 Likes

A funny iteration of this lol:

function hasAllChildren(parent, ...)
    return pcall(function()
        for _, childName in pairs({...}) do
            parent[childName]
        end
    end)
end
1 Like

Doesn’t work because functions can’t see varargs from scopes outside the function, gotta define the table outside the inner function like so:

function hasAllChildren(parent, ...)
	local args = {...}
	return pcall(function()
		for _, childName in pairs(args) do
			parent[childName]
		end
	end)
end

Also parent[childName] is not a valid statement, gotta assign the expression to a variable or call the value of the expression:

function hasAllChildren(parent, ...)
	local args = {...}
	return pcall(function()
		for _, childName in pairs(args) do
			local _ = parent[childName]
		end
	end)
end

Definitely still fun / hacky / cryptic :stuck_out_tongue: It’s also got the handy effect of telling you which child it fails to find first:

print(hasAllChildren(game.Workspace,  "Swag"))
false Swag is not a valid member of Workspace "Workspace"
1 Like

Best would probably be to make something like this:

local valArray = {“thing1”, “thing2”, “thing3”}

for i, val in pairs valArray do
    if player:FindFirstChild(val) then print(“found value” .. val) end
end

Nice! I wrote it up in the post so I didn’t see the errors. Glad to learn something new!

We can further “streamline” by passing the varang into the pcall func as a parameter to get this:

function hasAllChildren(parent, ...)
	return pcall(function(...)
		for _, childName in pairs({...}) do
			_ = parent[childName]
		end
	end, ...)
end

Also don’t need to local _ = yadayada because the for loop localizes it for us