Indexing - Checking the following value?

Hi, I was wondering if there were any way to check the following value when using a:
for i = 1,n?

I wish to create a loop that checks for items in the inventory and so far I’m using this method:
Apologies for the structure, I’m having trouble copy and pasting my code onto DevForum without it messing up entirely.

But is there any way to check if the current [i] Value is false and if the one following is not and if not, then the one prior becomes that one?

if inputOrder[1]["Tool"] == nil then
if inputOrder[2]["Tool"] ~= nil then
local Save = inputOrder[2]["Tool"]
inputOrder[2]["Tool"] = nil
inputOrder[1]["Tool"] = Save
end
end

By the way, the first two lines of codes are highly inefficient.

You can rewrite the first two lines as

if inputOrder[1]["Tool"] == nil and inputOrder[2]["Tool"] ~= nil then
    local Save = inputOrder[2]["Tool"]
        inputOrder[2]["Tool"] = nil
        inputOrder[1]["Tool"] = Save
    end
end

Using two if loops would be inefficient for tool finding as you’d have to keep running it; however, if you use an and loop, it would be easier for the game to check for the tools.

My apologies if you already know this; just want to provide an example.

1 Like

To get the next index in a for loop, you just need to add 1 to the current index:

local nextIndex = inputOrder[i + 1]

To check if a value is exclusively false (not just falsey), you need to implement a type check for booleans, like so:

if (type(inputOrder[i]) == "boolean" and inputOrder[i] == false) then

Combine these two with the “not equal” comparison you used previously (~=), and you’ll get the desired result:

if (type(inputOrder[i]) == "boolean" and inputOrder[i] == false and nextIndex ~= inputOrder[i]) then
    ...

Edit: See @Elttob’s answer below for a complete solution to your question. I have to be honest, I only read part of the question:

1 Like

Hi. Not sure if this is exactly what you wanted, but this code would check in the loop each value i and the next value in the table.

local n = 1337
for i = 1, n do
    if not inputOrder[n]["Tool"] and inputOrder[n + 1]["Tool"] then
        local Save = inputOrder[n + 1]["Tool"]
        inputOrder[n + 1]["Tool"] = nil
        inputOrder[n]["Tool"] = Save
    end
end

I think I didn’t get it because having tables for just 1 value is not very efficient…


Jokes aside, I think this is what you’re looking for:

-- this goes through every index from 1 to (length of inputOrder - 1)
-- the -1 is so we don't check the final item (because there's no next item after the last item)
for index=1, #inputOrder - 1 do
    local thisItem = inputOrder[index]
    local nextItem = inputOrder[index + 1]

    if thisItem["Tool"] == nil and nextItem["Tool"] ~= nil then
        -- move nextItem into thisItem, then set nextItem to nil
        thisItem["Tool"] = nextItem["Tool"]
        nextItem["Tool"] = nil
        break -- this stops the for loop once this if statement executes, remove this if you want to continue the loop
    end
end

7 Likes

This works great! Except - Now I have an issue where two slots are being taken up by a single item:

https://gyazo.com/58fad9ace4df59d64407da2ef15ffd8c

Have you tried removing the break statement from the code? Other than that, I’m not sure.

I did, yeh :confused: Unfortunately it didn’t work

Alright, interesting. I can’t think of any other solutions right now, so hopefully other people can help out too. Are you sure the problem isn’t elsewhere in the code?

Apologies that I couldn’t be of more help, but good luck with your problem :slightly_smiling_face:

1 Like

The issue seems to be that certain items aren’t being nilled / moving down at the right times - Therefore filling two slots up with the corresponding items?

function ChildRemoved(Child)
	if Child:IsA("Tool") then
		if Child.Parent ~= Player.Character and Child.Parent ~= Player["Backpack"] then
			for i = 1, #inputOrder do wait()
				if inputOrder[i]["Tool"] == Child then
					inputOrder[i]["Tool"] = nil
					break
				end
			end
			for index=1, #inputOrder - 1 do
			    local thisItem = inputOrder[index]
			    local nextItem = inputOrder[index + 1]
			
			    if thisItem["Tool"] == nil and nextItem["Tool"] ~= nil then
			        thisItem["Tool"] = nextItem["Tool"]
			        nextItem["Tool"] = nil
			    end
			end
		end
		Configure()
	end
end
1 Like

Still not totally sure - on first inspection, nothing in the code you’ve posted seems wrong. The wait() statement might not be needed, but that’s unrelated.

1 Like

I believe I found the issue -
It was within another function - The childAdded was firing as fast as the ChildRemoved and therefore contradicting itself! c:

function ChildAdded(Child)
		if Child:IsA("Tool") then
			local isNew = true
			for _, Value in pairs(inputKeys) do
				local Tool = Value["Tool"]
				if Tool then
					if Tool == Child then
						isNew = false
					end
				end
			end
			if isNew == true then
				for i = 1, #inputOrder do wait()
					local Tool = inputOrder[i]["Tool"]
						if inputOrder[i]["Tool"] == Child then
							inputOrder[i]["Tool"] = nil
						end
					if not Tool then
						inputOrder[i]["Tool"] = Child
						break
					end
				end
			end
			Configure()
		end
	end
1 Like