我怎样才能通过索引从 Nim 中的 OrderedTable 获取元素?

How can I get element by the Index from the OrderedTable in Nim?

Nim 有 OrderedTable 我如何通过索引而不是键获取元素?

如果可能 - 这是一个有效的操作,如 O(log n) 或更好?

import tables
let map = {"a": 1, "b": 2, "c": 3}.toOrderedTable

类似

map.getByIndex(1) # No such method

P.S.

我目前正在使用 seqTable 来提供键和索引访问,想知道它是否可以被 OrderedTable

取代
type IndexedMap = ref object
  list*: seq[float]
  map*:  Table[string, float]

由于有序表的内部结构,无法直接对其进行索引访问。按顺序访问元素的典型方式是:

import tables

let map = {"a": 1, "b": 2, "c": 3}.toOrderedTable

for f in map.keys:
  echo $f

基本上,访问 keys iterator. If you click through the source link in the documentation, you reach the actual iterator code:

  let L = len(t)
  forAllOrderedPairs:
    yield t.data[h].key

并且如果您遵循 the implementation of the forAllOrderedPairs template(建议您使用具有跳转至实现 功能的编辑器以更轻松地检查此类代码):

  if t.counter > 0:
    var h = t.first
    while h >= 0:
      var nxt = t.data[h].next
      if isFilled(t.data[h].hcode):
        yieldStmt
      h = nxt

不知道那里的性能,但它不会像访问简单的 list/array 一样快,因为 OrderedTable 的内部结构包含一个隐藏的 data 字段实际的键和值,并且需要额外的条件检查来验证条目是否实际被使用。此实现细节可能是一种妥协,以避免在删除单个项目后重新排列整个列表。

如果您的访问不频繁,使用迭代器查找值可能就足够了。如果基准测试显示它是一个瓶颈,你可以尝试 freezing 将 keys/values 迭代器放入本地列表并使用它,只要你不想进一步变异 OrderedTable.

或return您最初的想法是保留一个单独的列表。