Table sort problems.

Post Reply
azure_glass
Posts: 97
Joined: Wed Jul 25, 2012 12:35 pm

Table sort problems.

Post by azure_glass »

I gave something like that
Code: [show] | [select all] lua
HP_Console:cecho("\n["..CountNumberOfEnemies.."|"..HPstatus.."/6] "..MobName)
How to integrate these three variables in one record in table, and sort it by (at first) Number of enemies, (second) HP Status

So if i have input like
Code: [show] | [select all] lua
- 0 |_____0|1/6] pink orc.
- 3 |____00|2/6] fat elf. Atacked by xxxx, cccc and yyyy.
- 0 |000000|6/6] pinky.
- 1 |000000|6/6] brain. Atacked by ZZZZ.
Sorted to:
Code: [show] | [select all] lua
- 3 |____00|2/6] fat elf. Atacked by xxxx, cccc and yyyy.
- 1 |000000|6/6] brain. Atacked by ZZZZ.
- 0 |_____0|1/6] pink orc.
- 0 |000000|6/6] pinky.
Because i have clikable Labels like this.
Code: [show] | [select all] lua
ScreenK1W1:cecho("["..CountNumberOfEnemies.."".. HPstatus.." ".. MobName)
Screen1 = ScreenComand
AND
How to extract that information in sorted tables to that labels?
English is not my native language. If you don't understand what im writing ask. :)
Ubuntu 17.04, Mudlet 3.1

EulersIdentity
Posts: 27
Joined: Fri Jun 26, 2015 8:52 am

Re: Table sort problems.

Post by EulersIdentity »

If you have the time, google "sorting algorithms". It's actually pretty cool how many ways people have thought of to put a list of things in order. One easy (and dirty) way to do it is to copy everything into a table, then pull them out in the order you want. So if you put everything into a temporary table t you might do something like:
Code: [show] | [select all] lua
t = {}
t[1] = {CountNumberOfEnemies = 0,
          HPstatus = 1,
          MobName = "pink orc",
          }
t[2] = {...etc...}
Now send that stuff where you want it to go in order, pulling them out of the table as you go. This is why the table has to be a copy if you want to keep your original information:
Code: [show] | [select all] lua
function sortedEcho()
	tsorted = {} -- our destination table
    while next(t) do  -- go until we empty the table
		local maxIndex       --keep track of which entry has the biggest value
		local maxVal = 0  --keep track of which value is the biggest
        for i,v in ipairs(t) do  -- go through and find biggest value
			if v.CountNumberOfEnemies >= maxVal then
				maxIndex = 1
				maxVal = v.CountNumberOfEnemies
			end --if
		end --fpr
		-- we found the biggest value, remove it from the table and
		-- copy it to a new table or print it to the screen
		table.insert(tsorted,table.remove(t,maxIndex))
	end --while
end --function
If you then want to sort by HPstatus or whatever, you just apply the same type of logic to each chunk you want to sort.

If you wanted to just sort t without making a copy, bubble sort is really easy (sorting-algorithms) - (wikipedia). Here's the pseudocode:
Code: [show] | [select all] lua
procedure bubbleSort( A : list of sortable items )
   n = length(A)
   repeat 
     swapped = false
     for i = 1 to n-1 inclusive do
       /* if this pair is out of order */
       if A[i-1] > A[i] then
         /* swap them and remember something changed */
         swap( A[i-1], A[i] )
         swapped = true
       end if
     end for
   until not swapped
end procedure

EulersIdentity
Posts: 27
Joined: Fri Jun 26, 2015 8:52 am

Re: Table sort problems.

Post by EulersIdentity »

I kind of missed how you were getting your information coming in. The format that it's given to you will affect how you want to process it.

I was actually just working on a script to sort a particular format of table I'm using a lot. I'll throw it up here in case it's helpful to you. It takes a dictionary of dictionaries having the same key names and spits out a sorted list of the outer keys. If you were to output a table called myTable to an array called myArray, you could then do something like for i,v in ipairs(myArray) do myWindow:echo(i..", "..v[1]..", "..v[2].."\n") end and it would print a series of lines like "1, firstsortedkey, maximumvalue" -> "2, secondsortedkey, secondvalue" -> etc.
You could also echo any of the other key/value pairs in myTable by replacing the v[1]'s and v[2]'s with myTable[v[1]].someKey

I haven't implemented much error checking yet so use at your own risk.

Here's a link on repl.it if you want to see it run.
Code: [show] | [select all] lua
-- example
--[[
examplepd = {  
    ["174366"] = {
    name = "a hideous abomination",
    ppMean = 0,
  },
  ["43183"] = {
    name = "a Nuskuwen man",
    ppMean = 69.571428571429,
  },
  ["314932"] = {
    name = "a Vertani guard",
    ppMean = 75,
  },
--]]

-- 'pd' for 'parallel dictionary'
-- take the above type of dictionary, sort by field
-- returns a sorted array with entries {index,orignal key,field value}
-- eg: sorted = sortpd(examplepd,"ppMean")
---  display(sorted) -> {{1,"314932",75},{2,"43183",69.571428571429,},{3,"174366",0}}
---  uses insertion sort
function sortpd (pd,field)
	--TODO: error checking
	if not field then return false end
	if not pd then return false end
	--objective: get an indexed array of keys, ordered by 'field'
	local skeys = {}

	-- copy into skeys as {1={key,field},2={key,field},...}
	for k,v in pairs(pd) do
	    local entry = {}
		entry[1] = k
		entry[2] = v[field]
		table.insert(skeys,entry)
	end--for
	
	--sort skeys
	n = table.getn(skeys)
	size = table.getn(skeys)
	
	while n > 1 do
		local maxi = size
		for i= size, (size + 2 - n), -1 do
			if skeys[i-1][2] >=  skeys[i][2] then
				maxi = i-1
			end --if
	    end
	    
		--insert biggest element at head of table
		local tkey = table.remove(skeys,maxi)	
		table.insert(skeys,(size + 1 - n),tkey)

		n = n - 1
		
	end--while
	return skeys
end

EDIT: accidentally pasted a version with a couple of old syntax errors and debug messages

azure_glass
Posts: 97
Joined: Wed Jul 25, 2012 12:35 pm

Re: Table sort problems.

Post by azure_glass »

Thank you very much. :)

I try to implement this to my scripts.
English is not my native language. If you don't understand what im writing ask. :)
Ubuntu 17.04, Mudlet 3.1

EulersIdentity
Posts: 27
Joined: Fri Jun 26, 2015 8:52 am

Re: Table sort problems.

Post by EulersIdentity »

Double check that script to make sure it's sorting properly, I actually moved on to a different solution to my own sorting problem so I haven't had a chance to ensure that I didn't screw up the algorithm. I caught a silly error in an insertion sort I wrote right after that which I might have not caught previously. I'm putting together a class that'll sort itself, with a data type of an array of dictionaries, instead of a dictionary of dictionaries. Once I've finished it I'll post it to the forums. I'll put a copy of what I've done so far here and on repl.it so you can take a look. This one also uses insertion sort.

Again, be super careful about just copying any of this code straight out. I haven't foolproofed it yet.

Link to the repl.it, the class in its entirety with an example.

Here's the class with just the basic elements and its sorting function/method devoid of error checking:
Code: [show] | [select all] lua

function db.new(name,strict)
	local self = {}
	local name = name      -- name of the db
	local members = {}     -- this table will hold everything we care about
	
	--sort by 'field', sorts in ascending order unless second
	--argument is true
	--will not work on numbers stored as string, must coerce
	--returns true if runs successfully
     function self.sort(field,descending)		
		local n = 1
		 local size = table.getn(members)
		
		while n <= size do
			local maxi = n
			for i= n, (size-1) do
				if members[i+1][field]  >  members[maxi][field] then
					maxi = i+1
				end --if
    	                end -- for
    	                -- pull out biggest entry
                        local tentry = table.remove(members,maxi)
			if descending then
    			     table.insert(members,n,tentry)
                        else
                             table.insert(members,1,tentry)
                        end

     		n = n + 1
		end--while
		return true	
	end --sortKeys
    
	return self
                
end --db class type


Post Reply