Ipairs only comparing the first in array

  1. What do you want to achieve? The player has a list of all the names of equipment he owns. Upon loading up the game, ipairs will sort through both categories, matching two objects that have the same name and displaying it as a “usable” object in their inventory.

  2. What is the issue? This works as intended, but it only updates one object at a time. This is because GetChildren always lists from 1 to the end of the Array. Is there anyway to have the code go through all possible matches, and then determine if the player has the object or not.

This is really my first time dealing with shop like aspects, so if there’s any better way to do this, please let me know.

for number,equipment in ipairs(script.Parent:GetChildren()) do --goes through all the possible objects
	if equipment:IsA('Frame') then
		for i,owned in ipairs(player.utilities:GetChildren()) do --searches all of the players unlocked item
			if owned.Name == equipment.Name then -- if the names match, it makes the object "equippable"
				equipment.Buy.Visible = false
				equipment.Equip.Visible = true
			else
				equipment.Buy.Visible = true
				equipment.Equip.Visible = false
			end
		end
	end
end

Hi, the ipairs loop goes in order of all indices in a table until it hits nil. That means that if there is no data in table index 2, it will stop. Use pairs instead of ipairs to resolve this.

Hey! The list is about 15 indexes. There is enough data. I need it to go through all the objects, but it only stops after reading one.

try this

for number,equipment in pairs(script.Parent:GetChildren()) do --goes through all the possible objects
	if equipment:IsA('Frame') then
		for i,owned in pairs(player.utilities:GetChildren()) do --searches all of the players unlocked item
			if owned.Name == equipment.Name then -- if the names match, it makes the object "equippable"
				equipment.Buy.Visible = false
				equipment.Equip.Visible = true
			else
				equipment.Buy.Visible = true
				equipment.Equip.Visible = false
			end
		end
	end
end

This still has the same issue. It only updates based on the one match, and then doesn’t check the rest of the options to see if there are any more matches. It basically gives up after it finds one. Because of how sorting works in Roblox Studio, this means only the most recent change is visible.

Also, pairs should never be used with Arrays. That’s why you use ipairs.

I rewrote this script so it is more efficient.

-- when an item is bought, replace it with
owned[number] = true
-- instead of inserting the name of the equipment into a table

-- replace the loop with this
for number,equipment in pairs(script.Parent:GetChildren()) do --goes through all the possible objects
	if equipment:IsA('Frame') then
		if owned[number] == true then
			equipment.Buy.Visible = false
			equipment.Equip.Visible = true
		else
			equipment.Buy.Visible = true
			equipment.Equip.Visible = false
		end
	end
end

This looks great, I’m going to modify it slightly. Since these objects save, the data needs to be saved as a table to the datastore. Simply storing it inside the script is not going to work.

So you have two instance
assuming that :

  • script.Parent : his childs are all the possible equipements
  • player.utilities : his childs are the equipements that the player actually own

and you are looping through these and see if it matches ?
why don’t you loop through the script.Parent’s childs and then look into player.utilities if there is an isntance that has the same name ?
I would have done this :

for _, equipment in pairs(script.Parent:GetChildren()) do --goes through all the possible objects
	if equipment:IsA('Frame') then
		if player.utilities:FindFirstChild(equipement.Name) then
            equipment.Buy.Visible = false
		    equipment.Equip.Visible = true
        else
            equipment.Buy.Visible = true
			equipment.Equip.Visible = false
		end
	end
end
2 Likes

This seems to work the best. Instead of running two loops at once, it simply loops just the equipment list and then matches directly by searching with :FindFirstChild(). To be honest, I kind of wished I thought of this earlier, as this is a very simple solution. Thanks! also thanks @theWorldOfKoishi for the help as well.

3 Likes
for _, equipment in pairs(script.Parent:GetChildren()) do --goes through all the possible objects
	if equipment:IsA('Frame') then
		local state = player.utilities:FindFirstChild(equipment.Name)
		equipment.Buy.Visible = not state
		equipment.Equip.Visible = state
	end
end

didn’t know you could use variables like this. I didn’t know you could add “not” in front of them either. Thank you for this, this is a good example of code cleanup. Thank you so much!