Finding lowest value in a Inventory with tables

local inventory = {{Amount = 5},{Amount = 2},{Amount = 11},{Amount = 53}}



function returnLowest() -- loops through table and returns lowest value or false if no value exists
	local Lowest = false
	
	for index, value in pairs(inventory) do -- loops through inventory table
		
		if not Lowest then -- sets the first lowest
			Lowest = inventory[index]
		elseif value.Amount < Lowest.Amount then -- sets new lowest if amount is less than current lowest
			Lowest = inventory[index]		
		end
		
	end
	
	return Lowest
	
end

print(returnLowest().Amount)

-->> 2

function returnLowestWithSort()
	local sortedInventory = {} -- new inventory table
	
	for index, value in pairs(inventory) do
		sortedInventory[index] = value -- clones old inventory into new one
	end
	
	table.sort(sortedInventory, function(a, b) -- sorts the new inventory table
		return a.Amount < b.Amount
	end)
	
	return sortedInventory[1] -- returns the first table inside of the sorted inventory
	
end


print(returnLowestWithSort().Amount)

-->> 2

The goal of this code is to return which table has the lowest Amount

They both yield the same result, but which one is better to use, and is there a different/better way to achieve this?

3 Likes

The second function performs unnecessary code. The first function, although a bit modified, should be used:

local function returnLowest()
    local lowest
    for i = 1, #inventory do
        if not lowest or inventory[i].Amount < lowest.Amount then
            lowest = inventory[i]
        end
    end
    return lowest -- returns nil if no items are in inventory
end
1 Like

That’s a lot nicer, is a in pairs loop slower than for i = 1, #inventory?

function returnLowest()
    local lowest
    for i, v in pairs(inventory) do
        if not lowest or v.Amount < lowest.Amount then
            lowest = v
        end
    end
    return lowest -- returns nil if no items are in inventory
end

I like the look of it more, but if it’s going to make the code run slower then I wouldn’t want to use it

If you have to ask, it does make the code significantly slower if directly compared to each other, but in a case where it runs in Roblox, the difference is so negligible since a lot of other factors play bigger roles than choosing between numerical and generic for-loops. It runs slower because it needs to execute a function (pairs). However, you should pick the one that looks and feels better to code with. This is just my own preference to use numerical for-loops.

1 Like

You can do one less comparison lol, but basically makes 0 difference:

local function returnLowest()
    local lowest = inventory[1]
    for i = 2, #inventory-1 do
        if not lowest or inventory[i].Amount < lowest.Amount then
            lowest = inventory[i]
        end
    end
    return lowest -- returns nil if no items are in inventory
end

Typically if it’s just a negligible performance gain, then it doesn’t matter what you do - the point is picking which option seems more readable to you. For me personally, I would never use this piece of code and would opt to iterate through all indices of the table.

In the case that you aren’t using numerical indices, this is completely out of the question to do as is using the length operator on the table.

Yeah I did acknowledge the difference is negligible, but this method of iteration is faster and applicable for his case. He was not asking for the most general case - whatever works for him is fine. Ya need to chill my dude. In industry it is true that you readability is preferred over efficiency, but for small things like this I can choose to optimize my code or not just for the heck of it.

It doesn’t really matter though? You shave off a few miliseconds at best. I wouldn’t even call that faster (despite that being so), it’s a microoptimisation. In the new VM, overall iteration runs quicker.

The fact that I included that point is for the sake of knowledge and understanding that this isn’t applicable in every scenario because OP isn’t the only one who reads this post and the replies - others do as well. Therefore, it’s important to establish the distinction of which scenarios things can work for and in another case, where it doesn’t. Read my post carefully.

If you choose to “optimise” or shorten your code like this, that’s up to you. That doesn’t make my point any less valid and I’m unsure of what you’re trying to say or disprove here.

Yes, thanks for the borderline ad hominem. Not sure what about my post suggests aggression or something that’s the inverse of calm. Please leave my character out of your responses, only address what points I’m making.

Alright sorry about that then. I was in the wrong to believe you were just trying to make criticism. And yeah, it doesn’t really matter for the micro-optimization