Sorting Metatables

I’m trying to sort a table which has its value as another table.
How the table is built, is

local cmdData = {
		["Command"] = context.Name,
		["UserID"] = context.Executor.UserId,
		["UserName"] = context.Executor.Name,
		["RawText"] = context.RawText,
		["Response"] = context.Response,
		["Time"] = os.date("%c"),
		["Second"] = os.time()
	}

You see, I’m saving this to a database, the first key is the players userid, the second key is the Second. I’m then trying to sort the tables by the second, since I want to see the newest command last.

This is how I’m storing it in a datastore

local key = data.Second
local userIdKey = tostring(executorid)
local playerData = commandStorage:GetAsync(userIdKey) or {}
playerData[tostring(key)] = data
local success, errorMessage = pcall(function()
	commandStorage:SetAsync(userIdKey, playerData)
end)

And here is where I’m calling it, and sorting it.

local vid = players:GetUserIdFromNameAsync(tostring(victim))
if not vid then return "No user found by that name, try again." end
local log = data:GetAsync(vid)
if not log then return "Player has used no commands, or no commands have been found." end
table.sort(log, function(a,b)
	return tonumber(a) > tonumber(b)
end)
for i,v in log do
	if v.Command ~= "ModLogs" then
		context:Reply("Executor : "..v.UserName..", Command : "..v.Command..", Response : "..v.Response..", Time : "..v.Time)
			context:Reply("Raw Command : "..v.RawText)
			context:Reply("---------------")
		end
	end	

The problem is, this really should work, yet it doesn’t. for some reason the table.sort isn’t even going through I don’t think, I’m not too sure how table.sort works, but if I run it or I don’t, the output is always the same.

1 Like

This table is a Dictionary, table.sort only works on Arrays.

So how exactly would I sort this then

You can’t sort it the way you’re trying to sort it. You’re going to have to convert the table into a number index array

1 Like

Why do you wish to sort it anyway? In Dictionaries, you can index the table with the specific key that you want, and the data will be returned.

1 Like

Im trying to get all commands used by an admin and sort them from oldest to newest so I can make a moderation log

So you have a table like this:

{
   cmdData,
   cmdData,
   cmdData
}

? (cmdData represents the table you provided on your post)

1 Like

Yeah so basically how it is

Whenever someone uses a command, they are added into the datastore, their index is their userid, and their value is another table (hence the metatable). Inside this table, there is every command used by that player stored as a table, and the index of that is the os.time().

Datastore = {  
  ["mod who used command"] = {
     ["command 1"] = {"name" = command name, "executor" = the player}
  }
}

This is basically how it works, so when I want to get logs of every command used by a certain player, I would reach into the datastore with the key of the players userid, and it would return to me a bunch of tables aka every single command they have ever used.

Since the commands name is the os.time(), which is just however many seconds since some date in 1970 I believe, the newer commands would have a higher number as their name, allowing me to sort it. But, like you said you cannot sort a dictionary or metatable, so I was wondering the best way to go about sorting this data, so that way the log of the commands the moderator has used get returned to me in order from latest to newest.

If this is the case, then you can use the .Time or .Second property in your table.sort function, to compare the times and if one time is greater, then return that one.

Modify your log system so it works like this:

{ -- An Array so we can sort it.
    { -- Our main command data table
        ["Command"] = context.Name,
        ...
    },
    {
        ["Command"] = context.Name,
        ...
    },
}

This way, we can sort this table using this function below:

table.sort(log, function(a0, a1)
      -- Compare the a0's .Time or .Second property with the a1's.
end)

That’s still a dictionary is it not?

Yeah, so just use table.insert when you’re adding a new command. It’s saved in order anyways

Sure it’s saved in order, but it’s not given to you in order when you request it out of a datastore.

It should be? I don’t see why it wouldn’t be in order if you’re using table.insert

I can’t just use table.insert and save the key again, otherwise every single time I would have to take out the data, then table.insert, then resave the data (rather than just saving the data with the second as the key, skipping having to reload all the data.).

Edit : I don’t think there is another solution other than to not save it as a dictionary, which totally tanks the ease and efficiency of saving the data. I was hoping there was a kind of loophole that allows you to sort through tons of dictionaries, but I suppose not.

1 Like