【问题标题】:How to sort a dict in genie如何在精灵中对字典进行排序
【发布时间】:2016-12-27 09:43:46
【问题描述】:

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

我正在将一个 argument parser 从 python 重构为 Genie,但是我发现自己陷入了如何在将项目附加到列表之前从 dict 中排序。

在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 是类中的一个方法,我将 _options 声明为 _options:new dict of string, string

该部分代码不再有编译错误。我的问题是如何在将字典的元素添加到列表lines 之前对其进行排序?

【问题讨论】:

  • 当你说“参数解析器”时,你的意思是从命令行传递给程序的参数吗?
  • 我的意思是here...但我想我想要实现的目标与我面临的这个问题无关...问题是如何迭代一个dict已按字母顺序排序...
  • 如果您要解析命令行参数,您应该查看 GLib 的 OptionContext 和 OptionEntry。这对大多数用途都有好处。有关 Vala 的示例,请参阅 stackoverflow.com/questions/33431446/…

标签: vala genie


【解决方案1】:

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 的 stackoverflow 文档,这将是一个很好的例子):

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

【讨论】:

  • 如果您想要高效地从键到值进行搜索以及对键和值进行排序,那么 Gee 的 TreeMap 会更好。 TreeMap 实现了 Gee.SortedMap,因此您可以同时获得 ascending_keysascending_entries 属性。
  • 没错,选择最适合的数据结构总是明智的。您应该考虑将您的评论转换为答案,因为它是我的替代方案。
  • 谢谢两位! print(@ ... )和lines_add(@ ...)中@的作用是什么?
  • @lf_araujo 这称为插值字符串文字,字符串中具有$(美元)前缀的所有内容都将替换为计算表达式的结果。对于简单的 vars $varname 就足够了,对于复杂的表达式则需要括号 $(my_expression)
  • 或者更确切地说,这个概念被称为字符串插值,Vala 教程称它们为“字符串模板”,Genie 页面称它们为“文本模板”。无论如何,你应该明白了;)。
【解决方案2】:

基于 Thomas 和 Jens cmets,还可以使用 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])")

【讨论】:

    猜你喜欢
    • 2014-11-10
    • 2015-09-28
    • 1970-01-01
    • 2017-01-03
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多