问题
Update Solved the compiling error, now the only problem with the code is how to sort the dict alphabetically for pretty printing.
I am refactoring an argument parser from python into Genie, however I found myself stuck in how to sort the items form a dict before appending them to a list.
In python it is as simple as:
lines.append("Options:")
if len(self.options):
for name, option in sorted(self.options.items()):
lines.append(" %s: %s" % (name, option.values))
else:
lines.append(" [none]")
self.options is declared as self.options = {}
Now how can print the contents of the dict, but sorted?
Here is the code where I am stuck:
def ListOptions()
var lines = new list of string
lines.add("Options:")
if _options.size != 0
for name in _options.keys
lines.add(" %s: %s" % (name, _options.values))
else
lines.add(" [none]")
ListOptions is a method within a class, and I declared _options as _options:new dict of string, string
There is no compiling error in that section of the code anymore. My question is how to sort the elements of the dict before adding them to the list lines
?
回答1:
A dict of
is in reality a Gee.HashMap of K, V
, so you can look up what type the keys
property is.
keys
is of type Gee.Set of G
which doesn't have a sort method.
It does however derive from Gee.Collection of G
which we can use to make a new temporary list of string
(which is Gee.ArrayList
under the hood and does have a sort
method).
I have put this into a sort_string_collection
function (which could even be Generic, since it's not specific to strings, but I didn't bother because it's not easily possible with Genie at the moment).
With added test code, to make it a MCVE, the result looks like this:
[indent=4]
def sorted_string_collection (collection: Gee.Collection of string): Gee.Iterable of string
var l = new list of string
l.add_all (collection);
l.sort ()
return l;
def list_options (_options: dict of string, string): list of string
var lines = new list of string
lines.add("Options:")
if _options.size != 0
for name in sorted_string_collection (_options.keys)
lines.add(@" $name: $(_options[name])")
else
lines.add(" [none]")
return lines
init
var opts = new dict of string, string
opts["z"] = "23"
opts["abc"] = "42"
opts["pi"] = "3.141"
var l = list_options (opts)
for var s in l
print (s)
Or even more minimalistic (if we ever get to use stackoverflow Documentation for Genie, this would be a good example):
[indent=4]
def sorted_string_collection (collection: Gee.Collection of string): Gee.Iterable of string
var l = new list of string
l.add_all (collection);
l.sort ()
return l;
init
var dic = new dict of string, string
dic["z"] = "23"
dic["abc"] = "42"
dic["pi"] = "3.141"
for k in sorted_string_collection (dic.keys)
print (@"$k: $(dic[k])")
回答2:
Based on Thomas and Jens comments, one can also use TreeMap. Here is how it would look:
[indent=4]
uses
Gee
init
var dic = new TreeMap of string, string
dic["z"] = "23"
dic["abc"] = "42"
dic["pi"] = "3.141"
for k in dic.ascending_keys
print (@"$k: $(dic[k])")
来源:https://stackoverflow.com/questions/39052435/how-to-sort-a-dict-in-genie