|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Tue Jul 29, 2008 3:18 am
How to sort a database variable by value if some of the values are the same? |
Is there currently a way to sort a database variable by (numerical) value? I found this thread where it was suggested that you generate another database based on the original database, only with the keys and values reversed. That would almost work for me, except that sometimes the values in my original database are duplicates. So, for example, a key in my original database might have a value equal to 10, and so might a different key, and another, etc. If I had two or more keys with the same value, when those keys become values in the mirror database variable, there would be only a single key and value instead of more, and the key would only be equal to whatever last overwrote it.
To put it another way, let's say my database variable says this:
Blahblah 10
LOLWUT 15
Norly 10
Intertubes 10
Something 12
The mirror database would end up saying this:
10 Intertubes
12 Something
15 LOLWUT
And it would lose the crucial keys Blahblah and Norly. :-/
Is there any way I can sort a database variable by numerical value without having to create a mirror database? |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Tue Jul 29, 2008 4:20 am |
What is it that you are trying do here anyway? I think perhaps you are trying to do something complicated that doesn't need to be complicated.
|
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Tue Jul 29, 2008 5:17 am |
I figured out a way to do it without having to sort the database, but it was extra steps and would have been much easier if I could just sort the database variable by value.
In the game I play (DragonRealms) you have to get ranks in certain skills to level. The skills are divided into skill sets. Some level requirements are simple: x ranks in a specific skill. Others are not so simple: x overall ranks in a certain skillset, or X number of skills in a skillset must be at least Y rank or higher, etc.
It's the second thing that made me want to sort a database variable. There are nine skills in the lore skillset I can learn, and each level it doesn't matter which skills they are, but I need to have three of them to be at least Y rank. I have an alias I run that reads in my current skills and ranks and tells me what I need to level. For most requirements that's enough to do some simple math.
For the lore skills, though, it's not, since I have to determine which skills are my top three. I have to put them in a database variable with the key as the skill and the value as my ranks in it. I wanted to sort them descending so I could just have it look at the top three things in the variable database, calculate them against what I need to level, and tell me. I can't do the mirror database thing though because I might have the same number of ranks in two or more skills, which would make the script useless; if I had the same ranks in two or all three of my top three skills, it would actually ignore two or three of my top three skills and urge me to waste time on skills I do not need to level.
So anyway, to get around it I just had it generate a stringlist variable that's equal to the values of everything in the database. Then it sorts the stringlist descending. Then it does a LOOPDB where it checks what skill has the same ranks as the first number in the string (the highest number). Once it finds it, it assigns that skill as my top lore skill and breaks from the loop. Then it does the same thing for the second number in the string, and as long as it's not the previously mentioned skill, it assigns it to my second lore skill. Then it does the same thing for the third number in the string, as long as it's not the first and second skill, and assigns it as my third lore skill. This way, it doesn't matter if I have the same ranks in two or more skills or not; it just checks for another skill of that same value that isn't the one(s) it already found.
It ends up being like, five lines of code instead of two, but it works perfectly so I'll take it. It would be simpler to just be able to sort a database variable by value, though. I couldn't figure out a command for it, if it exists. |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Tue Jul 29, 2008 9:59 pm |
Ah. Hit a snag with my work-around... sorting the stringlist does things like this:
49|42|4|37|26|15|0|0|0
As you can see, it makes my script think my third-highest skill has 4 ranks, rather than 37. I tried manually to make that 4 a "04" but it just deletes the leading zero, so that's not an option either.
So as of right now, there's no way to sort it like I want, right? If anyone has any idea for another way I could do this, it would be appreciated; I can't mirror database or do this, so I'm hard-pressed to think up a third way. If it comes to me, I'll post it here though. |
|
|
|
Guinn Wizard
Joined: 03 Mar 2001 Posts: 1127 Location: London
|
|
_________________ CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;) |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Jul 29, 2008 11:39 pm |
Hrm, that looks like a very old topic. I guess I will right a solution off of the top of my head.
Code: |
#SHOW %sort(%subregex(@var,"^([^=]*+)=([^|]*+)(?=\||\z)", "%right(%concat(""000"",""\2""),3) --- \1"),1) |
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Tue Jul 29, 2008 11:45 pm |
Hmm, neither of those work for me... the value sorting alias from that thread ends up returning seven skills instead of nine. It looks like it's just doing a mirror database, and like I said, I have more than one skill with the same values so that will not work... in this case, it only registered one of the skills with zero ranks. Then the #SHOW %sort there gives me this odd result:
wind=0|vocals=50|teaching=29|string=0|scholarship=43|percussion=0|mech=38|appraisal=15|4 --- animal |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Jul 30, 2008 3:25 am |
I did say it was off of the top of my head. Looking at the result and guessing what the original variable might have been I would say it requires 2 small corrections, and consequent adjustments for one of them.
Code: |
#SHOW %sort(%subregex(@var,"(^|\|)([^=]*+)=([^|]*+)(?=\||\z)", "\1%rightback(%concat(""000"",""\3""),3) --- \2"),1) |
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Caled Sorcerer
Joined: 21 Oct 2000 Posts: 821 Location: Australia
|
Posted: Wed Jul 30, 2008 8:34 am |
Thanks for that one, Viji. I've been trying to write a function to do this without using %subregex for a while now, and it has been annoying me. Assuming that works, I should be able to plug the line into my function and never have to worry about it again :D
|
|
_________________ Athlon 64 3200+
Win XP Pro x64 |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 4:59 pm |
charneus: The SortByVal alias doesn't work for me. :-/ #SHOW @postsort doesn't return anything at all... This is what happens:
Starting out: #SHOW @lorelist
gives me this: animal=4|mech=39|scholarship=44|teaching=30|wind=0|appraisal=16|vocals=51|percussion=0|string=0
Then SortByVal @lorelist mentions this, echo-style:
Variable: + postsort (String)
Then #SHOW @postsort returns nothing at all, if it's supposed to. When I manually check the variable, it is indeed empty.
Then #SHOW @lorelist says the same thing it said before.
Vijilante: Now the show says this... it's too over my head for me to figure out what might be wrong:
004 --- animal|%rightback(%concat("000","50"),3) --- vocals|%rightback(%concat("000","43"),3) --- scholarship|%rightback(%concat("000","38"),3) --- mech|%rightback(%concat("000","29"),3) --- teaching|%rightback(%concat("000","15"),3) --- appraisal|%rightback(%concat("000","0"),3) --- wind|%rightback(%concat("000","0"),3) --- string|%rightback(%concat("000","0"),3) --- percussion |
|
|
|
Guinn Wizard
Joined: 03 Mar 2001 Posts: 1127 Location: London
|
Posted: Wed Jul 30, 2008 6:26 pm |
Vijilante, am I right in thinking that you can't guarantee the order of the items in a db variable (in CMUD at least, maybe you could in zMUD)?
e.g.
Code: |
test={one=1|two=2|three=3}
#showdb @test
test={three=3|two=2|one=1}
#showdb @test |
Both produce the same display regardless of the order they're entered.
If Nattie just wants to show the items in the right order once then I'm guessing your regex will do it, but if they want to then store those items in that order are they just SOL? |
|
_________________ CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;) |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 6:41 pm |
Ah, yeah, for what it's worth, I need to store them. I actually don't ever need to display them, but my scripts need to know what they are to figure out what to do. :-) Or rather, if I could actually sort it correctly, I could write a really good script that would need to have those values stored.
I think I'm SOL, lol, unless/until numerical sorting is available. I wish it didn't delete leading zeros, because then I might be able to work around it. |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Wed Jul 30, 2008 7:14 pm |
Should be this to sort:
Code: |
#show %sort(%subregex(@db, "(^|\|)([^=]*+)=([^|]*+)(?=\||\z)", \1%right(%concat( "000", \3), 3) --- \2)) |
or to return the highest first:
Code: |
#show %sort(%subregex(@db, "(^|\|)([^=]*+)=([^|]*+)(?=\||\z)", \1%right(%concat( "000", \3), 3) --- \2),1) |
The problem was he used %rightback and not %right. :-P
Output for your little db in the first post is:
04---Norly|10---BlahBlah|10---Intertubes|12---Something|15---LOLWUT
and
15---LOLWUT|12---Something|10---Intertubes|10---BlahBlah|04---Norly |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 7:18 pm |
That still has single-digit numbers mixed in with double (or more) digit numbers that start with the same number. :(
52---vocals|44---scholarship|40---mech|4---animal|31---teaching|17---appraisal|0---wind|0---string|0---percussion
Huh... I wonder why it worked for you and not on my db variable? |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Wed Jul 30, 2008 7:33 pm |
Are you sure your db value is still 04 and not 4?
Example I just used above was the following:
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<var name="db" type="Record" copy="yes">Intertubes=10|LOLWUT=15|BlahBlah=10|Something=12|Norly=04</var>
</cmud>
|
|
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 7:39 pm |
I'm confused by the question... The db value for "animal" has always been 4. I can't make it 04 if I want to, because it deletes leading zeros. That's the reason I have problems sorting it, because it always sticks it in with the stuff in the 40s (or 400s, or 4000s, etc).
Or are you asking something else? |
|
|
|
oldguy2 Wizard
Joined: 17 Jun 2006 Posts: 1201
|
Posted: Wed Jul 30, 2008 7:48 pm |
No it doesn't. Look at the db I just posted above your post just now. For that matter look at this one.
Code: |
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
<var name="mydb" type="Record" copy="yes">test1=05|test2=06|test3=08|test5=010|test6=11|test7=1|test8=12</var>
</cmud>
|
Output:
12-test8|11-test6|1-test7|08-test3|06-test2|05-test1|010-test5
*note - I changed the output to show "-" and not "---".
Regardless, as you can see it didn't remove the leading zeros. |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 7:52 pm |
That's so weird. When I go to the database variable and try to add a 0 in front of the 4, it immediately deletes it. I've tried this many times.
The text from the game reads just "4" so I would have to add zeros to it. But every time I've tried it simply does not let me. Now I'm really confused. |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Wed Jul 30, 2008 9:59 pm |
Hah, now here's something weird. Now that I've uninstalled and reinstalled, it doesn't delete leading zeros. WTH? Oh well, not gonna complain.
|
|
|
|
Taz GURU
Joined: 28 Sep 2000 Posts: 1395 Location: United Kingdom
|
Posted: Thu Jul 31, 2008 12:26 am |
*lol* ah the wonders of computers
|
|
_________________ Taz :) |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Fri Aug 15, 2008 6:55 pm |
The bug fixes for %subregex in 2.36 have this working perfectly now. The code I used to test it was
Code: |
#ADDKEY var {x=3|f=1|z=12|abc=7|xyz=9|def=3}
#SHOW %sort(%subregex(@var,"(^|\|)([^=]*+)=([^|]*+)(?=\||\z)", "\1%rightback(%concat(""000"",""\3""),3) --- \2"),1) |
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Nattie Apprentice
Joined: 24 Jul 2008 Posts: 109
|
Posted: Fri Aug 15, 2008 7:41 pm |
Oh awesome, I'll try that out hopefully tonight or tomorrow when I get a moment. Thanks! :D
|
|
|
|
|
|