2

I need to create a zero table with length specified by a variable. In python, I can write:

arr = [0] * size

But in lua, I can only do this like:

local arr = {} for i=1,size do arr[i] = 0 end

Are there any ways that I can do that in lua with python style? Thank you all.

2
  • Well, if you don't mind convoluted solutions, there is also this one: local arr = load('return {'..('0,'):rep(size)..'}')() Commented Mar 25, 2016 at 15:11
  • Another convoluted solution is available since Lua 5.3: local arr = {table.unpack(setmetatable({},{__index=function()return 0 end}),1,size)} Commented Mar 26, 2016 at 12:13

2 Answers 2

5

There doesn't seem to be any way to create this using the language's syntax. Instead, consider creating a function that generates an array of size. Then you can simply say arr = newArray(5) or similar.

function newArray (size)
    local arr = {}
    for i=1, size do
        arr[i] = 0
    end
    return arr
end

You can extend this feature to create an array initialized with any value:

function newArray (size, value)
    value = value or 0
    local arr = {}
    for i=1, size do
        arr[i] = value
    end
    return arr
end

EDIT: the above examples are not intended as perfect solutions and I highly discourage copying code without understanding it's limitations. Indeed, if you need to allow boolean values, alter the function to suit your needs. The edit that made value an optional argument was an example of convenience. The suggestion that the code allow false is a good suggestion, but the answer demonstrates an option rather than an exhaustive solution.

Sign up to request clarification or add additional context in comments.

4 Comments

Better make value optional: define newArray(size,value) and add value = value or 0 before the loop.
@lhf: It's intended to match the Python syntax, and the Python syntax doesn't make the value optional.
@NicolBolas True! I did make lhf's suggested change because lua is its own language and that style will be more cohesive. Embracing compiler/interpreter features to make robust code is a good philosophy in most languages. Feature abuse is another can of worms entirely (macros in C come to mind as a commonly abused feature).
Arrays are not allowed to be initialized with false?! Better use value = value == nil and 0 or value (or an explicit if).
0

Not that I would recommend it, but you could get pretty close to Python's syntax in Lua:

local A = require"A"  -- see below for the implementation of module "A"

-- ...

local t = A[0] * 10

for i,v in ipairs( t ) do
  print( i, v )
end

Here is the code for module "A":

local M_meta = {}
local M = setmetatable( {}, M_meta )

local function forbid_operation()  -- to prevent mistakes
  error( "not a regular table, operation forbidden!" )
end

local O_meta = {
  __index = forbid_operation,
  __newindex = forbid_operation,
  __pairs = forbid_operation,
  __ipairs = forbid_operation,
  __mul = function( self, n )
    if type( self ) == "number" then
      self, n = n, self -- swap values in case of e.g. `3 * A[0]`
    end
    local t, v = {}, self[ M_meta ]
    for i = 1, n do
      t[ i ] = v
    end
    return t
  end,
  __metatable = false,
}

local function index_or_call( self, v )
  -- use M_table as a private key: no-one but this module
  -- can access it, because it is local
  return setmetatable( { [ M_meta ] = v }, O_meta )
end

M_meta.__index = index_or_call  -- A[0] syntax
M_meta.__call = index_or_call  -- A(0) syntax is also allowed
M_meta.__newindex = forbid_operation
M_meta.__pairs = forbid_operation
M_meta.__ipairs = forbid_operation
M_meta.__metatable = false

return M

The module actually returns a table with a customized __index (and __call) metamethod. When __index or __call is invoked, another table is returned with the given value stored in a private field and a __mul metamethod this time. The __mul metamethod retrieves the value from the private field and creates the array of the requested length with the given value, and returns it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.