Having Trouble Making a (relatively) Simple Sorting Algorithm

Alright so I’m trying to create a sorting algorithm for a game I’m working on.

  • Theres 6 rarities, valued from 1-6
  • Theres two currencies, valued from 1-2
  • Theres prices for both currencies.

In that order, prioritizing the lowest possible of each value, how could I sort these all into one array so I can them list them in a Gui?

Thanks in advance.

Sort them once per category to sort by. First the lowest priority, then next lowest, then highest priority. I.e. three table.sort calls with different comparison functions.

EDIT: Actually, table.sort might not be stable so multiple sorts might not work. Try it and see if it works tho.

EDIT: Actually this is not the best idea anyway. Just have your comparison function first check the high priority, then the next highest priority if they’re equal on the first one. E.g.

function sortByProperties(array, ...)
	local properties = {...}
	table.sort(array, function(a, b)
		for _, prop in ipairs(properties) do
			assert(a[prop.name] and b[prop.name])
			--if a[prop] == b[prop] * prop.dir then continue end -- This is unncessary, but shows all three cases
			if a[prop.name] > b[prop.name] * prop.dir then return false end
			if a[prop.name] < b[prop.name] * prop.dir then return true end
		end
	end)
	return true --They're equal on all properties
end

local itemSortProps = {
	{name="Rarity", dir=-1},
	{name="Price", dir=1}, 
}

local items = {
	{Price=10, Rarity=1},
	{Price=10, Rarity=2},
	{Price=20, Rarity=1},
	{Price=30, Rarity=-1},
}

sortByProperties(items, unpack(itemSortProps))
for _, item in ipairs(items) do
	print(item.Price, item.Rarity)
end

Try changing the order of Rarity and Price in itemSortProps, you'll get different results.

Also I read somewhere that I cannot sort dictionaries, is this true?
I have a dictionary holding all the items and their values.

Could i get an example of how I would sort them by two categories?
I understand how I would sort it by one thing but I’m not sure how I would do it by two things.

What if you multiply each items rarity by its currency to give it a value, then sort by value?

This could potentially work since the item rarities are pretty much directly correlated to the price. Ill look into it.

You could use a custom table.sort thingy?

This is the default sort script which you could modify:

table.sort(Table, function(a, b)
    return a < b
end)

I know I need to use table.sort but my issue is that I need to sort multiple values so im not sure how to go about it.

if your using a UIGridLayout or UIListLayout

you can use this to sort the GUI without having a table sorted
https://developer.roblox.com/en-us/api-reference/property/UIGridStyleLayout/SortOrder

if you use Enum.SortOrder.LayoutOrder then you can do something like this

GuiObject.LayoutOrder = raritie * 10000 + currencie1 * 100 + currencie2

or if you use Enum.SortOrder.Name then something like this maybe i’m not sure how large your prices get so i only padded the string with upto 6 leading zeros maybe you could use less or more depending on how large the prices get

GuiObject.Name = raritie .. string.format("%06d", currencie1) .. string.format("%06d", currencie2)

Heres how I’ve got it set up.

local items = {
	{
		Name = "CoolString",
		Rarity = 1,
		CurrencyType = 1,
		Price = 100
	},
	{
		Name = "CoolString2",
		Rarity = 3,
		CurrencyType = 2,
		Price = 220
	},
	{
		Name = "CoolString3",
		Rarity = 6,
		CurrencyType = 2,
		Price = 500
	},
}

Simple example of a neatly sorted array of items. To show it in a GUI, I suggest using a list/grid layout, then looping through the array and cloning a template with each item’s information. Or at least that’s how I’d do it.

To sort them, create a new (empty) array and add each item and slot them to the bottom of the list through a for loop.