|
ralgith Sorcerer
Joined: 13 Jan 2006 Posts: 715
|
Posted: Tue Dec 11, 2007 5:11 am
Numerical Sorting - New function suggestion: %numsort() |
Well, recently I wrote a script that needed to take a string list with all numerical values in zMUD and sort them out into proper order.
zMUD does not have a function to do this, as %sort() returns 10, 100, 4, 500.... etc etc...
So, I figured it would be nice if CMUD DID have such a function, since it is relatively simple.
I mean, it's a TINY little bit of code that could even be included in the next beta if Zugg felt like it.
Though, unlike my alias it should have a little error checking built in, just in case the list variable does not contain all numbers... Or treat all non-numeric params as 0.
Here is the alias I made in zMUD to do the same job:
Code: |
#ALIAS SortNums {
#while (%numitems(@Blah)) {
#var temp %item(@Blah,1)
#loop %numitems(@Blah) {
#IF (%int(%item(@Blah,%i)) < %int(@temp)) {#var temp %item(@Blah,%i)}
}
#ADDITEM Display @temp
#DELITEM Blah @temp
}
}
|
For those that care, here is the zMUD GD Topic On this: http://forums.zuggsoft.com/forums/viewtopic.php?p=121197
[edit]
Oops ;) Forgot the %int around the vars in the if statement... it was only comparing the first digit of each var without it...
[/edit] |
|
|
|
Arlie Wanderer
Joined: 09 Jun 2006 Posts: 62 Location: Florida
|
Posted: Tue Dec 11, 2007 7:34 am |
For the sake of speed / efficiency, wouldn't it make more sense to use local variables to hold the number of items for the loop and the temp as well? Not trying to be critical, just "thinking out loud" about a few ways this could be enhanced as a temporary solution. :)
|
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Dec 11, 2007 9:58 am |
It'd be better, really, if sorting a variable did this automatically. There are very few cases where you'd mind 110 coming before 1050.
|
|
|
|
Guinn Wizard
Joined: 03 Mar 2001 Posts: 1127 Location: London
|
Posted: Tue Dec 11, 2007 10:01 am |
What would sort do if the list was
110|1050|a|b
does it treat them all as strings or sort the numbers as numbers and the strings as string? |
|
_________________ CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;) |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Tue Dec 11, 2007 10:05 am |
Doesn't seem very complex to me - the strings that it can coerce into numbers, it does. That's the only way something like this would work.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Dec 11, 2007 6:47 pm |
Sorry, but this isn't as trivial as you'd think and won't be done for the public version. Right now CMUD is using the Sort property of the internal TStrings Delphi data structure. And this uses alphabetic sorting and not numeric sorting.
|
|
|
|
ralgith Sorcerer
Joined: 13 Jan 2006 Posts: 715
|
Posted: Tue Dec 11, 2007 9:25 pm |
Arlie wrote: |
For the sake of speed / efficiency, wouldn't it make more sense to use local variables to hold the number of items for the loop and the temp as well? Not trying to be critical, just "thinking out loud" about a few ways this could be enhanced as a temporary solution. :) |
Probably, yes. I wrote it for zMUD though, and then again... since both vars used are created OUTSIDE of this function, then they couldn't be local... but using local vars you could cut it down to 1 global var instead of 3. |
|
|
|
ralgith Sorcerer
Joined: 13 Jan 2006 Posts: 715
|
Posted: Tue Dec 11, 2007 9:27 pm |
Zugg wrote: |
Sorry, but this isn't as trivial as you'd think and won't be done for the public version. Right now CMUD is using the Sort property of the internal TStrings Delphi data structure. And this uses alphabetic sorting and not numeric sorting. |
Thats why I suggested it as a separate function from %sort(), because I knew it would have to involve manual code. Still I don't see it being too far above trivial... I just wrote up a function in C to do it in under 5 minutes with error checking... Too bad I never learned Pascal/Delphi or I'd just write it up as pseudo code in Delphi for ya ;) |
|
|
|
Llwethen Novice
Joined: 08 Dec 2006 Posts: 37 Location: Lancaster,Oh
|
Posted: Tue Dec 11, 2007 11:46 pm |
pseudo code is language specific???
|
|
|
|
shalimar GURU
Joined: 04 Aug 2002 Posts: 4690 Location: Pensacola, FL, USA
|
Posted: Tue Dec 11, 2007 11:52 pm |
if it is a list of all numbers... just pad the left end with 0's so all the members have the same length
|
|
_________________ Discord: Shalimarwildcat |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Dec 12, 2007 12:32 am |
Quote: |
I just wrote up a function in C to do it in under 5 minutes with error checking... Too bad I never learned Pascal/Delphi or I'd just write it up as pseudo code in Delphi for ya ;) |
That's not the hard part. I can do that trivially myself too. But getting it integrated with the rest of CMUD and working with the string list hash tables properly is the trickier part. |
|
|
|
ralgith Sorcerer
Joined: 13 Jan 2006 Posts: 715
|
Posted: Wed Dec 12, 2007 3:42 am |
Llwethen wrote: |
pseudo code is language specific??? |
heh, not really... but when I write pseudo code I prefer to make it look close... ie mailer code... instead of just the standard pseudo code of:
if condition one
then do this
else if cond two
do this
else
do that
Nice one though ;)
My improper use of pseudo when my meaning is closer to mailer ;)
Zugg wrote: |
That's not the hard part. I can do that trivially myself too. But getting it integrated with the rest of CMUD and working with the string list hash tables properly is the trickier part. |
Now I feel dumb lol, forgot all about the hash tables. Yeah. Thats trickier by far.
Got so focused on what *I* was doing and thinking that I lost sight of the overall picture, doh!
One of my faults I'm afraid. And I do have ever so many. |
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Tue Jan 29, 2008 4:03 am |
We can use lua to do any type of sorting you need for example:
Code: |
<func name="NSort" language="Lua" id="1">
<value>if zs.numparam < 1 then return "" end
local tbl = zs.param(1)
if type(tbl) ~= "table" then return tbl end
--local errstr = "All Items in list given to NSort must be a number"
--table.sort(tbl,function(a,b) return assert(tonumber(a),errstr)< assert(tonumber(b),errstr) end)
table.sort(tbl)
return table.concat(tbl,"|")
</value>
</func>
|
Just pass in a custom function to table.sort (like the one I have commented out) and you can make it sort anyway you wish. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
Zhiroc Adept
Joined: 04 Feb 2005 Posts: 246
|
Posted: Wed Jan 30, 2008 2:39 pm |
Dharkael wrote: |
Code: |
...
--table.sort(tbl,function(a,b) return assert(tonumber(a),errstr)< assert(tonumber(b),errstr) end) |
Just pass in a custom function to table.sort (like the one I have commented out) and you can make it sort anyway you wish. |
Haven't spend the time to learn Lua yet, but that is always the way to go when doing a general sorting function: Let the user define a function.
But I'm not sure the above works? Sorting functions usually require you to return -1, 0, or 1 in order to say whether the two items are less than, equal, or greater than. I love how Perl makes a "<=>" and "cmp" operator do that without needing a bunch of if's. |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Wed Jan 30, 2008 6:37 pm |
The function argument to table.sort takes two arguments, both of which are items in the list. It should return true when the first argument should go before the second in the list, and false when it should go behind it. You can read more about it in the Lua manual.
|
|
|
|
Dharkael Enchanter
Joined: 05 Mar 2003 Posts: 593 Location: Canada
|
Posted: Thu Jan 31, 2008 5:03 am |
I know what you mean about comparison functions usually returning -1,0 or 1 Zhiroc.
I thought the same thing when I first looked at the table.sort method.
If you have a function cmp(f,s) which returns true if the first argument is less than the second.
You can get the equiv of the perl <=> or cmp operators in Lua by doing
Result = cmp(A,B) and -1 or cmp(B,A) and 1 or 0
Its not as nice looking as the perls <=> operator but it does the same thing.
It also demonstrates that we can get all three values with a comparison function returning a boolean value. |
|
_________________ -Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style." |
|
|
|
|
|