I have models in my game (plots) named like so
100_Player1
102_Player2
etc
Now I’m trying to reference these plots from other scripts by checking for the players name in the model.
local playersPlot = plots:WaitForChild(player.Name)
I’m not sure which string manipulation method I should be using. To also note, I do NOT want to put this into a loop of any kind or anything. I would prefer it to be on the 1 line, simple and clean.
If the plot names only contain the player name and aren’t the exact name string, you’d have to use a loop and string.find to get the correct plot
I think this is by far the simplest way, trying to compress this sort of thing probably won’t result in it being simpler or cleaner. Shorter code is not always simpler or easier to read.
local playersPlot = nil
for k,plot in next, plots:GetChildren() do
if string.find(plot.Name, player.Name) then
playersPlot = plot
break
end
end
If you really want to have it on 1 line of code you could do something like adding tags of the player’s name (with CollectionService) and simply use CollectionService:GetTagged(playername)[1]
But if that’s too much trouble I’d recommend following an alternative (e.g. using loops + string.find or what xuefei123 said)
I think this is a fine solution, but somewhat unnecessary compared to just using a loop. It’s not necessarily cleaner, and with 0 practical difference in efficiency
However if you need to access the plot number for some reason, this could work quite well, or you could just have a table of plots, (e.g. keys as plot number, with a table containing the player value and the physical model), something like this:
local Plots = {}
Plots[102] = {
Player = Player2,
Model = workspace.Plot100
}
If the numbers at the start of your plot name will always be three digits followed by an underscore, this function should work for you:
-- Instance waitForPlot(Instance parent, string playerName)
local function waitForPlot(parent, playerName)
-- check if plot already exists.
for _, child in ipairs(parent:GetChildren()) do
if child.Name:sub(5) == playerName then
return child
end
end
-- wait for plot to be added.
local plot
repeat
plot = parent.ChildAdded:Wait()
until plot:sub(5) == playerName
return plot
end
local playersPlot = waitForPlot(plots, player.Name)
Are these ID’s unique? Random? What do they represent? Is it possible to get our hands on it any other way then the folder/model?
I guess its sort of a cheap way around it, its also a form of loop.
function getPlot(Player)
local PlotsTable = Plots:GetChildren()
table.foreach(PlotsTable, function(index, plot)
if string.find(plot.Name, Player) then
return plot
end
end)
end
They did not want to use a loop because it was complicated and unclean. I have made a function that uses a loop under the hood, but can be used itself in one line. It is impossible to realistically solve this issue without using a loop (or rethinking his structure altogether).
string.find is unreliable as there may be people with similar names. For instance, using string.find(plot.Name, Player) on 100_AbiZinho and 101_AbiZinho1, assuming I’m the Player, could really cause some issues.
Though the chances are low, we must account for this as well.
If you want it to be a simple and clean 1 line, you’re gonna have to either change the way you name plots, or add some additional code to save a reference the plot IDs so you can just do :WaitForChild(someTable[player.Name].PlotId.."_"..player.Name). I’d go with the former though!
A solution to this would be using string.find(plot.Name, "^%d+_" .. player.Name .. "$") since that’ll make sure it fits the exact format of the original post.