#nim-lang
#nim-lang
Вопрос:
В Nim есть OrderedTable
как я могу получить элемент по его индексу, а не по его ключу?
Если это возможно — это эффективная операция, как O(log n)
или лучше?
import tables
let map = {"a": 1, "b": 2, "c": 3}.toOrderedTable
Что-то вроде
map.getByIndex(1) # No such method
Постскриптум
В настоящее время я использую оба seq
и Table
для предоставления доступа как по ключу, так и по индексу и задаюсь вопросом, можно ли заменить его на OrderedTable
type IndexedMap = ref object
list*: seq[float]
map*: Table[string, float]
Ответ №1:
Прямой доступ по индексу к упорядоченным таблицам отсутствует из-за их внутренней структуры. Типичный способ доступа к элементам по порядку -:
import tables
let map = {"a": 1, "b": 2, "c": 3}.toOrderedTable
for f in map.keys:
echo $f
В основном, доступ к итератору ключей. Если вы перейдете по ссылке на исходный код в документации, вы получите фактический код итератора:
let L = len(t)
forAllOrderedPairs:
yield t.data[h].key
И если вы будете следовать реализации шаблона forAllOrderedPairs (рекомендуется использовать редактор с возможностями перехода к реализации, чтобы упростить проверку такого кода):
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
Понятия не имею о производительности там, но это будет не так быстро, как доступ к простому списку / массиву, потому что внутренняя структура OrderedTable
содержит скрытое data
поле с фактическими ключами и значениями, и требуется дополнительная условная проверка, чтобы убедиться, что запись действительно используется. Эта деталь реализации, вероятно, является компромиссом, позволяющим избежать перетасовки всего списка после удаления одного элемента.
Если ваши обращения нечасты, может быть достаточно использования итератора для поиска значения. Если сравнительный анализ показывает, что это узкое место, вы можете попробовать заморозить итератор ключей / значений в локальном списке и использовать его вместо этого, если вы не хотите еще больше мутировать OrderedTable
.
Или вернитесь к своей первоначальной идее ведения отдельного списка.