How to sort a dict in genie

一个人想着一个人 提交于 2019-12-08 03:54:33

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!