如何在精灵中对字典进行排序

How to sort a dict in genie

更新 解决了编译错误,现在代码的唯一问题是如何按字母顺序对字典进行排序以实现漂亮的打印。

我正在将 python 中的 argument parser 重构到 Genie 中,但是我发现自己陷入了如何在将项目附加到列表之前对它们进行排序的问题。

在python中很简单:

    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 声明为 self.options = {}

现在如何打印dict的内容,但排序?

这是我卡住的代码:

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 是 class 中的一个方法,我将 _options 声明为 _options:new 字符串的字典,字符串

那段代码没有编译错误了。我的问题是如何在将字典的元素添加到列表之前对它们进行排序 lines?

一个dict of实际上是一个Gee.HashMap of K, V,所以你可以查一下keys属性是什么类型。

keys 的类型 Gee.Set of G 没有排序方法。

然而,它确实派生自 Gee.Collection of G,我们可以使用它来创建一个新的临时 list of string(它是 Gee.ArrayList 在引擎盖下并且确实有一个 sort 方法).

我已经把它放到一个 sort_string_collection 函数中(它甚至可以是通用的,因为它不是特定于字符串的,但我没有打扰因为 it's not easily possible with Genie at the moment)。

添加测试代码,使其成为 MCVE,结果如下所示:

[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)

或者更简约(如果我们曾经使用过 Genie 的 Whosebug 文档,这将是一个很好的例子):

[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])")

根据 Thomas 和 Jens 的评论,也可以使用 TreeMap。它的外观如下:

[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])")