Можно ли заставить индексирование таблицы Lua начинаться с нуля? - PullRequest
13 голосов
/ 07 августа 2010

У меня проблема с Луа. Используется индексация по одному. В языке есть возможность устанавливать значение в индексе 0, но значение не будет учитываться как часть длины таблицы, а манипуляции со строками все еще основаны на одном. Поэтому я думаю, что эта функция является чем-то особенным, а не индексацией.

Мне не нужен флейм с единичным или нулевым. Я просто спрашиваю, есть ли возможность принудительной индексации на основе нуля.

Ответы [ 9 ]

4 голосов
/ 20 июня 2017

Работать с 0-индексированными массивами на самом деле довольно просто:

local array={
[0]="zero",
    "one",
    "two"
}

for i=0,#array do
    print(array[i])
end

Вы можете использовать #array, не вычитая 1, потому что оператор длины фактически возвращает самый высокий индекс (технически, ключ перед первым нулем), а не фактическую "длину" (которая в любом случае не имеет смысла в Lua).

Для строковых операторов вам, вероятно, придется просто создавать дубликаты функций (хотя может быть и лучший способ)

ipairs() также поддерживает только 1 индексирование, поэтому вам придется определить свою собственную функцию или просто использовать вместо нее обычный for.

3 голосов
/ 15 сентября 2011

Я знаю, что этому вопросу уже 1 год, но я подумал, что будущим искателям будет интересно узнать, что CFF Explorer содержит язык сценариев (Lua с патчами), который имеет патч с 0 индексами:1002 *http://www.ntcore.com/files/cffscriptv2.htm

Кроме того, в приведенном выше документе автор заявил, что ему пришлось отключить большинство стандартных функций библиотеки, поскольку они несовместимы с массивами с 0 индексами, поэтому, пожалуйста, повторите ваш мыслительный процессоб этой проблеме:)

2 голосов
/ 22 ноября 2011

Комментарий Эонила к ответу Понзао: Реальная проблема заключается в том, что базовым языком должен быть язык индексации на основе C. Индексирование данных, обменивающихся между скриптом и хостом, должно быть правильно переведено.

Если вы хотите представить структуры данных C для Lua, используйте userdata для их упаковки. Вы можете заставить индексирование вести себя так, как вам нравится, используя метатаблицы. Таким образом, вы можете обеспечить правильный перевод.

2 голосов
/ 07 августа 2010

Я думаю, что в Lua уже есть функция, которая необходима для того, чтобы сделать его 0-основанным.К сожалению, функция, на которую я ссылаюсь, - это лицензия Lua с открытым исходным кодом.

Мне не удалось найти патч или форк Lua, который изменил бы основанную на 1 природу языка.изменение его на 0 также нарушило бы обратную совместимость.Потеря всех текущих дополнительных модулей может быть слишком большой ценой для простоты использования.

1 голос
/ 06 февраля 2013

Грязный подход с некоторыми недостатками:

function zeroIndexed(tbl)
    local mt = {}
    mt.data = tbl
    mt.__index = function(t, k)
        return mt.data[(type(k) == "number" and k + 1 or k)]
    end
    mt.__newindex = function(t, k, v)
        mt.data[(type(k) == "number" and k + 1 or k)] = v
    end
    mt.__len = function()
        return #mt.data
    end
    return setmetatable({}, mt)
end
t = zeroIndexed({5, 6, 7})
print(t[0], t[1], t[2])
t[0] = 4
print(t[0], #t)
t[#t] = 8
print(t[#t - 1], #t)

Lua 5.2 выходы:

5       6       7
4       3
8       4

В Lua 5.1 #t возвращает 0, поскольку __len metamethod не учитывается для таблиц и строк.

Но помните, что table.insert и другие методы таблиц здесь больше не будут работать, потому что вставка теперь выполняется через t[#t] = x.

Я не рекомендую использовать это.

1 голос
/ 07 августа 2010

Даже если бы в источниках Lua было #define TABLE_START_INDEX 1 (а я не верю, что это так), вы бы сильно застрелились в ногу, изменив это. Это связано с тем, что большинство библиотек используют индексирование на основе 1. Таким образом, любой код, выполняющий что-то вроде следующего, сломается.

для i = 1, #t do ... end

Конечно, вы можете использовать итераторы или даже создавать вспомогательные функции, чтобы избежать этого.

функция get_first (t) возвращает t [1] конец

Вероятно, хотя реальная проблема, которую вы пытаетесь решить, сложнее, чем изменение индексации с 0 на 1.

0 голосов
/ 15 марта 2019

Прямой ответ: Измените исходный код Lua. Измените все операции на lua table на base-0.

Здесь я делаю это вместе с Luaстандартная библиотека.Доступен бинарный файл Windows.

http://lua -users.org / wiki / CountingFromOne (некоторые комментарии внизу)

https://github.com/farteryhr/lua-base-0 (см. Коммитистория для того, что было изменено)

В основном грязная работа о +1 -1, и большинство из них было сделано.

Пожалуйста, напишите несколько тестовых случаев (охватывающих столько деталей языка, скольковозможно) и сообщать об ошибках.

(На данный момент известно, что что-то не так с metatable, но я не могу найти время для его изучения)

0 голосов
/ 05 ноября 2017

Вы можете исправить этот недостаток, используя итератор, который знает о различных базах индексов:

function iarray(a)
  local n = 0
  local s = #a
  if a[0] ~= nil then
    n = -1
  end
  return function()
    n = n + 1
    if n <= s then return n,a[n] end
  end
end

Однако вам все равно придется добавить нулевой элемент вручную:

Использованиепример:

myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
  -- do something with element e
end
0 голосов
/ 06 декабря 2011

ответ на ваш вопрос: нет, нет способа заставить весь процесс, который обрабатывает lua, с индексом 0, потому что сейчас, насколько я знаю, #table идет от 1, «n» и без него индекс 0 его На мой взгляд, довольно бесполезно, но в зависимости от того, что вы хотите сделать, вы можете сравнить, есть ли у вас что-то или нет, с таблицами, 1, который читает продукты, 1, который читает доход, и если продукты увеличиваются, у вас больше, если продукты = 1, то у вас ноль, так что вы просто читаете 1 таблицу, а не 2, я надеюсь, что я все проясню <, <</p>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...