sorting string keys of dictionaries

george
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
Perhaps you could use StringListSort
http://quest5.net/wiki/StringListSort

jaynabonne
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
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
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
It's not a core (ASLX) function but rather implemented in the expression parser (from what I can see).

Liam315
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.

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums