I have an issue with Lua. It uses one-based indexing. The language has a feature to set value at index 0, but the value won't be counted as a part of table length, and string manipulations are still one-based. Therefore, I t开发者_Python百科hink the feature is something special rather than about indexing.
I don't want a flame about one-based or zero based. I'm just asking is there a feature to force zero-based indexing.
Working with 0-indexed arrays is actually pretty simple:
local array={
[0]="zero",
"one",
"two"
}
for i=0,#array do
print(array[i])
end
You can use #array
without subtracting 1 because the length operator actually returns the highest index (technically, the key before the first nil), not the actual "length" (which wouldn't make sense in Lua anyway).
For string operators, you'll probably have to just create duplicate functions (though there might be a better way)
ipairs()
also only supports 1 indexing, so you'll have to define your own function or just use a regular for
instead.
I know this question is already 1 year old, but I thought future seekers would be interested in the fact, that CFF Explorer contains a scripting language (Lua with patches), which has 0-indexed table patch:
http://www.ntcore.com/files/cffscriptv2.htm
Also, in the document above, the author stated that he had to disable most of the standard library functions, because they're incompatible with 0-indexed arrays, so please reiterate your thought process about this issue :)
The direct answer: Modify the source code of Lua. Change all the operations on lua table
to base-0.
Here I'm doing it, along with Lua standard library. Windows binary available.
http://lua-users.org/wiki/CountingFromOne (some comment at the bottom)
https://github.com/farteryhr/lua-base-0 (see the commit history for what have been modified)
Mostly dirty work about +1 -1, and most of them have been done.
Please write some test cases (covering as many details of the language as possible) and report bugs.
(For now it's known there's still something wrong with metatable, but I can't find time to investigate it)
I think that that Lua already has the feature that you need to make it 0-based. Unfortunately the feature that I refer to is Lua's open source license.
I was unable to find a patch or fork of Lua that changed the 1-based nature of the language.
Unfortunately forking Lua to change it to 0-based would also break backwards compatibility. Loss of all the current add-on modules may be too great a price to pay for ease of use.
Eonil's comment to ponzao's answer: Real problem is base language should be the C which is 0-based indexing language. Indexing data interchanging between script and host must be correctly translated.
If you want to expose C data structures to Lua, use userdata
to package them up. You can make the indexing behave however you like with these using metatables. This way, you can ensure correct translation.
Even if there was a #define TABLE_START_INDEX 1
in the Lua sources (which I don't believe there is) you would pretty much shoot yourself in the leg by changing this. This is due to most libraries using 1-based indexing. Thus any code doing something like the following would break.
for i = 1, #t do ... end
You can of course use iterators or even create helper functions to avoid this.
function get_first(t) return t[1] end
Probably though the actual problem you are trying to solve is harder than changing from 0 to 1-based indexing.
Dirty approach with some drawbacks:
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 outputs:
5 6 7
4 3
8 4
In Lua 5.1 #t
returns 0
because the __len metamethod
isn't respected for tables and strings.
But remember that table.insert
and other table methods won't work here anymore because inserting is now done via t[#t] = x
.
I don't recommend using this.
You can fix this lua-flaw by using an iterator that is aware of different index bases:
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
However, you still have to add the zeroth element manually:
Usage example:
myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
-- do something with element e
end
the answer to your questuion its no, theres no way to force all the process that lua handles with an index 0, because right now as far as i know #table goes from 1,"n" and without it index 0 its pretty much useless, at my sight, but depends what you want to do, you could compare if you have something or not, from to tables, 1 that reads the products, 1 that reads the income, and if products increase you have more, if products are = 1 then you have nil, so you just read 1 table, rather than 2, i hope i make my self clear <,<
I've found when interfacing with a 0 indexed language (C for example) it is easiest to just not use index 0. It is wasteful of memory, but changing lua is pretty absurd.
精彩评论