Json and tables

I am playing with JSON for the first time and I am having a hard time trying to get the number of children inside an element. This is my json file:

{ "name": "Eyes of the Prophet", "format": { "orientation": "portrait" }, "pages": { "page1": { "width": 768, "height": 3072, "interface": { "layer1": { "file": "p1\_page1.png", "width": 768, "height": 1024, "x": 384, "y": 512 }, "layer2": { "file": "p1\_page2.png", "width": 768, "height": 1024, "x": 384, "y": 1536 }, "layer3": { "file": "p1\_page3.png", "width": 768, "height": 1024, "x": 384, "y": 2560 } } } } }

and this is the code I am using:

local json = require "json" local function jsonFile(filename ) local path = system.pathForFile(filename, system.DocumentsDirectory ) local contents local file = io.open( path, "r" ) if file then contents = file:read("\*a") print(contents) io.close(file) end return contents end local t = json.decode( jsonFile( "sample.json" ) ) print(#t.pages) 

I would like to know how many “pages” I have (under the PAGES bracket), as well as how many “layers” I have inside a page. I tried all possible combinations without success to get the number of elements inside the table. :frowning:

Any ideas what I am doing wrong?

There is nothing wrong with your code.

The problem is that the “#” operator only works with numerically-indexed tables. The code below shows you the difference:

local t = {} t[1] = "a" t[2] = "b" print("#t=", #t) -- this returns 2 local t = {} t["a"] = "c" t["b"] = "d" print("#t=", #t) -- this returns 0

So you have two options:

  1. Calculate the length of the table by yourself by doing:

    local c=0 for k,v in ipairs(t.pages) do c= c +1 end print(“length=”, c)

Or…

  1. Change your JSON content so the pages table can be a numerically-indexed table. The JSON would be like this (I added a 2nd page to the table)

    { “name”: “Eyes of the Prophet”, “format”: { “orientation”: “portrait” }, “pages”: [{ “width”: 768, “height”: 3072, “interface”: { “layer1”: { “file”: “p1_page1.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 512 }, “layer2”: { “file”: “p1_page2.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 1536 }, “layer3”: { “file”: “p1_page3.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 2560 } } }, { “width”: 768, “height”: 3072, “interface”: { “layer1”: { “file”: “p2_page1.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 512 }, “layer2”: { “file”: “p2_page2.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 1536 }, “layer3”: { “file”: “p2_page3.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 2560 } } }] }

I’d make a slight change - ipairs is the same thing, it just works for numerically indexed tables. Just plain ol’ pairs() is what you want.

  • C

Beautiful! Thanks a lot Renato!

There is nothing wrong with your code.

The problem is that the “#” operator only works with numerically-indexed tables. The code below shows you the difference:

local t = {} t[1] = "a" t[2] = "b" print("#t=", #t) -- this returns 2 local t = {} t["a"] = "c" t["b"] = "d" print("#t=", #t) -- this returns 0

So you have two options:

  1. Calculate the length of the table by yourself by doing:

    local c=0 for k,v in ipairs(t.pages) do c= c +1 end print(“length=”, c)

Or…

  1. Change your JSON content so the pages table can be a numerically-indexed table. The JSON would be like this (I added a 2nd page to the table)

    { “name”: “Eyes of the Prophet”, “format”: { “orientation”: “portrait” }, “pages”: [{ “width”: 768, “height”: 3072, “interface”: { “layer1”: { “file”: “p1_page1.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 512 }, “layer2”: { “file”: “p1_page2.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 1536 }, “layer3”: { “file”: “p1_page3.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 2560 } } }, { “width”: 768, “height”: 3072, “interface”: { “layer1”: { “file”: “p2_page1.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 512 }, “layer2”: { “file”: “p2_page2.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 1536 }, “layer3”: { “file”: “p2_page3.png”, “width”: 768, “height”: 1024, “x”: 384, “y”: 2560 } } }] }

I’d make a slight change - ipairs is the same thing, it just works for numerically indexed tables. Just plain ol’ pairs() is what you want.

  • C

Beautiful! Thanks a lot Renato!