Display contents of tables in lua
Asked Answered
I

8

26

What I'm trying to do is display the content of table using the following code in Lua.

local people = {
   {
   name = "Fred",
   address = "16 Long Street",
   phone = "123456"
   },

   {
   name = "Wilma",
   address = "16 Long Street",
   phone = "123456"
   },

   {
   name = "Barney",
   address = "17 Long Street",
   phone = "123457"
   }

}
for k, v in pairs(people ) do
    print(k, v)
end

The output I got is:

1   table: 0x9a2d8b0
2   table: 0x9a2d110
3   table: 0x9a2cb28
Indoaryan answered 30/1, 2017 at 17:50 Comment(0)
E
22

To display nested tables you will have to use nested loops.

Also, use ipairs to iterate through array-like tables, and pairs to iterate through record-like tables.

local people = {
   {
       name = "Fred",
       address = "16 Long Street",
       phone = "123456"
   },
   {
       name = "Wilma",
       address = "16 Long Street",
       phone = "123456"
   },
   {
       name = "Barney",
       address = "17 Long Street",
       phone = "123457"
   }
}

for index, data in ipairs(people) do
    print(index)

    for key, value in pairs(data) do
        print('\t', key, value)
    end
end

Output:

1   
        phone   123456          
        name    Fred            
        address 16 Long Street          
2   
        phone   123456          
        name    Wilma           
        address 16 Long Street          
3   
        phone   123457          
        name    Barney          
        address 17 Long Street  
Errecart answered 30/1, 2017 at 18:25 Comment(2)
@Errecart How can one dynamically tell whether a table is array-like or record-like?Affright
Lua tables can be both, or either, at the same time... but you could look at a table at a given time and check if all keys are integers ranging from 1 to length (or compare if using ipairs and pairs results in the same sequence) - in which case it's an array, otherwise it's probably record/mixed.Strobotron
M
34

This recursively serializes a table. A variant of this code may be used to generate JSON from a table.

function tprint (tbl, indent)
  if not indent then indent = 0 end
  local toprint = string.rep(" ", indent) .. "{\r\n"
  indent = indent + 2 
  for k, v in pairs(tbl) do
    toprint = toprint .. string.rep(" ", indent)
    if (type(k) == "number") then
      toprint = toprint .. "[" .. k .. "] = "
    elseif (type(k) == "string") then
      toprint = toprint  .. k ..  "= "   
    end
    if (type(v) == "number") then
      toprint = toprint .. v .. ",\r\n"
    elseif (type(v) == "string") then
      toprint = toprint .. "\"" .. v .. "\",\r\n"
    elseif (type(v) == "table") then
      toprint = toprint .. tprint(v, indent + 2) .. ",\r\n"
    else
      toprint = toprint .. "\"" .. tostring(v) .. "\",\r\n"
    end
  end
  toprint = toprint .. string.rep(" ", indent-2) .. "}"
  return toprint
end

running your table through this:

 local people = {
   {
   name = "Fred",
   address = "16 Long Street",
   phone = "123456"
   },

   {
   name = "Wilma",
   address = "16 Long Street",
   phone = "123456"
   },

   {
   name = "Barney",
   address = "17 Long Street",
   phone = "123457"
   }

}


print (tprint(people))

generates this:

  {
  [1] =     {
      name= "Fred",
      phone= "123456",
      address= "16 Long Street",
    },
  [2] =     {
      name= "Wilma",
      phone= "123456",
      address= "16 Long Street",
    },
  [3] =     {
      name= "Barney",
      phone= "123457",
      address= "17 Long Street",
    },
}
Mattland answered 30/1, 2017 at 18:54 Comment(0)
E
22

To display nested tables you will have to use nested loops.

Also, use ipairs to iterate through array-like tables, and pairs to iterate through record-like tables.

local people = {
   {
       name = "Fred",
       address = "16 Long Street",
       phone = "123456"
   },
   {
       name = "Wilma",
       address = "16 Long Street",
       phone = "123456"
   },
   {
       name = "Barney",
       address = "17 Long Street",
       phone = "123457"
   }
}

for index, data in ipairs(people) do
    print(index)

    for key, value in pairs(data) do
        print('\t', key, value)
    end
end

Output:

1   
        phone   123456          
        name    Fred            
        address 16 Long Street          
2   
        phone   123456          
        name    Wilma           
        address 16 Long Street          
3   
        phone   123457          
        name    Barney          
        address 17 Long Street  
Errecart answered 30/1, 2017 at 18:25 Comment(2)
@Errecart How can one dynamically tell whether a table is array-like or record-like?Affright
Lua tables can be both, or either, at the same time... but you could look at a table at a given time and check if all keys are integers ranging from 1 to length (or compare if using ipairs and pairs results in the same sequence) - in which case it's an array, otherwise it's probably record/mixed.Strobotron
C
13

If you need to dump table contents within Neovim code, you can use this method, which is built into the standard lib.

print( vim.inspect(table) )

From the Neovim documentation:

Lua standard modules lua-stdlib

The Nvim Lua "standard library" (stdlib) is the vim module, which exposes various functions and sub-modules. It is always loaded, thus require("vim") is unnecessary. You can peek at the module properties: :lua print(vim.inspect(vim)) Result is something like this:

{
  _os_proc_children = <function 1>,
  _os_proc_info = <function 2>,
  ...
  api = {
    nvim__id = <function 5>,
    nvim__id_array = <function 6>,
    ...
  },
  deepcopy = <function 106>,
  gsplit = <function 107>,
  ...
}
Cristionna answered 19/3, 2023 at 14:22 Comment(0)
P
6

If you have static predefined field names in your data records, this simpler version may work for you:

for i,t in ipairs(people) do
  print('Record',i)
  print('Name',t.name)
  print('Address',t.address)
  print('Phone',t.phone)
  print()
end
Palestine answered 31/1, 2017 at 0:8 Comment(1)
This has the advantage that you can choose the order the fields are shown.Bookworm
G
2

Assuming your data structures are JSON serializable (like your example above) you can just cheat and use rxi/json.lua (MIT License) to aid in pretty printing objects. Just drop json.lua into your project and this will work:

json = require "json"
for k, v in pairs(people) do
    print(k, json.encode(v))
end
1       {"address":"16 Long Street","name":"Fred","phone":"123456"}
2       {"address":"16 Long Street","name":"Wilma","phone":"123456"}
3       {"address":"17 Long Street","name":"Barney","phone":"123457"}
Gifferd answered 25/11, 2020 at 1:1 Comment(1)
what an elegant solution!Potsdam
S
1

Solution 1: py.repr https://github.com/waketzheng/luapy

$ wget https://raw.githubusercontent.com/waketzheng/luapy/main/python.lua

py=require('python')
> tab = { 1, 2, 3 }
> py.repr(tab)
[
    1,
    2,
    3
]
> tab = { a=1, b=2, c=3 }
> py.repr(tab)
{
    "c": 3,
    "a": 1,
    "b": 2
}
> tab = { a='a', b='b', c='c', d='d', e='e', f='f', g='g' }
> py.repr(tab)
{
    "g": "g",
    "a": "a",
    "b": "b",
    "c": "c",
    "d": "d",
    ...
}

Solution 2: lu.prettystr https://luaunit.readthedocs.io/en/latest/#pretty-printing

$ wget https://raw.githubusercontent.com/bluebird75/luaunit/main/luaunit.lua

> lu = require('luaunit')
> t1 = {1,2,3}
> t1['toto'] = 'titi'
> t1.f = function () end
> t1.fa = (1 == 0)
> t1.tr = (1 == 1)
> print( lu.prettystr(t1) )
{1, 2, 3, f=function: 00635d68, fa=false, toto="titi", tr=true}
Sufferance answered 17/10, 2020 at 13:10 Comment(0)
H
0

I'm not sure what IDE you are working out of. But for any reason you and anyone else who finds this thread, is working in Visual Studio Code, the Lua Debug extension will do a great job in displaying all your associative array values for the custom tables you build.

What I really like about it, is that you can display not only your initial values, but if you decide to later change a value, you can do that with this extension and see your adjustments, all through the "Debug Console" tab.

I took your exact example, and simply typed in people into the debug, and go all values displayed.

Hanky answered 5/1, 2020 at 4:58 Comment(0)
Q
0

We can also ignore index:

for _, person in pairs(people) do
    for k,v in pairs(person) do
        print(k,v)
    end
end
Quirites answered 16/10, 2023 at 10:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.