sorting string keys of dictionaries

george
13 Mar 2014, 04:48
So in another thread I rather blithely assumed sorting a dictionary in pure Quest (not JS), while maybe tedious, wouldn't be that hard to do. However I was playing around with it and there seems to be a couple of stumbling blocks, the main one is that you can't cast a string to a char.

Since you can't compare strings as far as I can tell, comparing chars is the next best thing. But while you can compare chars, I don't see a way to cast strings to chars, so if you start with a string key from a dictionary, is it possible to compare those string keys in order to sort them?

Using the FLEE cast() didn't work, and even if it did work it wouldn't be a great solution anyway since it won't convert to JS.

Is JS the best option here?

The only pure Quest solution I can think of at the moment is to maintain a mapping of numbers to chars, and strings to numbers, such that given a string like "s", you could find a number (say 20) which is mapped to the char 's'. Then you could get the char 's' that way. But it's quite roundabout.

Pertex
13 Mar 2014, 07:50
Perhaps you could use StringListSort
http://quest5.net/wiki/StringListSort

jaynabonne
13 Mar 2014, 08:05
You have the Asc function at your disposal. Here is a quick and dirty and rather ugly quick implementation of a "string less than" function.

<!--Saved by Quest 5.5.5173.27901-->
<asl version="550">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="SortTest">
<gameid>235470e7-3e53-4464-ada0-28904679c835</gameid>
<version>1.0</version>
<firstpublished>2014</firstpublished>
<start type="script">
<![CDATA[
msg(StringIsLessThan("a", "b"))
msg(StringIsLessThan("B", "D"))
msg(StringIsLessThan("ab", "adc"))
msg(StringIsLessThan("z", "abc"))
]]>
</start>
</game>
<function name="StringIsLessThan" parameters="s1, s2" type="boolean">
<![CDATA[
len1 = LengthOf(s1)
len2 = LengthOf(s2)
len = len1
if (len > len2) {
len = len2
}
i = 1
done = false
while (i <= len and not done) {
c1 = Asc(Mid(s1, i, 1))
c2 = Asc(Mid(s2, i, 1))
if (c1 < c2) {
done = true
ret = true
} else if (c1 > c2) {
done = true
ret = false
}
i = i + 1
}
if (not done) {
ret = len1 < len2
}
return (ret)
]]>
</function>
<object name="room">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
</object>
</asl>


It might be helpful as well to explain why you want to sort the keys. There might be a different solution to the same problem. (BTW, I was surprised that direct string comparison doesn't work. I would have bet money on it.)

jaynabonne
13 Mar 2014, 08:07
Pertex, how in the world did you find that? :) (That's a bit of a rhetorical question.) I did a search on the Wiki for "sort" and the only link from the List page was for ObjectListSort. That's definitely the solution to the question.

george
13 Mar 2014, 14:17
Thanks guys, I completely missed Asc! StringListSort would certainly work too. I noticed it's one of those functions that's in the wiki but doesn't show up when you filter for library elements in Quest itself.

jaynabonne
13 Mar 2014, 15:27
It's not a core (ASLX) function but rather implemented in the expression parser (from what I can see).

Liam315
14 Mar 2014, 12:03
george wrote:I noticed it's one of those functions that's in the wiki but doesn't show up when you filter for library elements in Quest itself.


http://quest5.net/wiki/Category:All_Fun ... t_Commands

That is the single most helpful page of the entire wiki, you can find a lot of functions that you wouldn't have even thought to search for but come in very useful.