## File lines to table (lua question)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

### File lines to table (lua question)

I'd like to know who to load the lines of a file into a table or an array.

Here's an exemple file:

Code: Select all

0,0,0,0
1,0,1,1
0,1,0,0
0,0,0,0
And I would like to put those lines into a bidimensional array or table like so:

Code: Select all

line[1][1]=0
...
line[1][4]=0

line[2][1]=1
line[2][2]=0
...
line[2][4]=1

line[3][1]=0
...
line[3][4]=0
.
.
.
I already found this on the web:

Code: Select all

map_file = assert(io.open('map.txt'))
local line_data = {}
for line in map_file:lines() do
local character_array = {}
for i = 1, #line do
character_array[#character_array + 1] = line[i];
end
line_data[#line_data + 1] = character_array
end
But whenever I do print(unpack(line_data[1])) I get an empty output, I've also tried print(line_data[1][1]) and I get nil.
print(line_data[1]) gives me table: 00xxxxxx

LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping

raidho36
Party member
Posts: 1984
Joined: Mon Jun 17, 2013 12:00 pm

### Re: File lines to table (lua question)

Print(table) yields table pointer hexadecimal value, which is no use to your Lua code, but if you have it means that table is there.

The problem with your code is Lua strings implementation, that is they are not arrays and you can't index them as such. You instead use substirngs.

Lua have true immutable strings, and working with them might be a pain.

Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

### Re: File lines to table (lua question)

raidho36 wrote:Print(table) yields table pointer hexadecimal value, which is no use to your Lua code, but if you have it means that table is there.

The problem with your code is Lua strings implementation, that is they are not arrays and you can't index them as such. You instead use substirngs.

Lua have true immutable strings, and working with them might be a pain.
But there is a way to divide each number separated by ',' in each line into a variable, right ?
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping

raidho36
Party member
Posts: 1984
Joined: Mon Jun 17, 2013 12:00 pm

### Re: File lines to table (lua question)

You can try using foreach loop with string.gsub function.

Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

### Re: File lines to table (lua question)

raidho36 wrote:You can try using foreach loop with string.gsub function.
Ok, I'm gonna look into that, I'll post back in a few minutes
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping

Omnivore
Prole
Posts: 18
Joined: Fri Jun 28, 2013 12:51 am
Location: West Coast

### Re: File lines to table (lua question)

Code: Select all

function string_split(text, sep, out)
sep, out = sep or "%s", out or {}
for s in string_gmatch(text, "([^"..sep.."]+)") do
out[#out + 1] = s
end
return out
end

or similar should do the job (cut and paste from my utility.lua file). Use like:

Code: Select all

local some_table = string_split("0,1,0,1,0", ",")

gsub won't quite give you want you expect -- edit: unless you match for the desired content instead of the delim, lol nice
Last edited by Omnivore on Wed Jul 31, 2013 6:02 pm, edited 1 time in total.
Lua lou aye, ah no its, lua louie

MPQC
Citizen
Posts: 65
Joined: Fri Jun 28, 2013 2:45 pm

### Re: File lines to table (lua question)

Alternative to Omnivores.. First argument is your string, second is delimiter. I used this previously in my game before I swapped formats, it works wonders.

Code: Select all

function split(str, pat)
local t = {}  -- NOTE: use {n = 0} in Lua-5.0
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = str:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = str:find(fpat, last_end)
end
if last_end <= #str then
cap = str:sub(last_end)
table.insert(t, cap)
end
return t
end
Usage:

Code: Select all

local lines = "1 2 3 4 5"
local setting = split(lines, " ") -- Splits on every space
setting[1] == "1"
setting[2] == "2"

For your case, split by newline, then split by commas. Done.

Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

### Re: File lines to table (lua question)

Omnivore wrote:

Code: Select all

function string_split(text, sep, out)
sep, out = sep or "%s", out or {}
for s in string_gmatch(text, "([^"..sep.."]+)") do
out[#out + 1] = s
end
return out
end

or similar should do the job (cut and paste from my utility.lua file). Use like:

Code: Select all

local some_table = string_split("0,1,0,1,0", ",")

gsub won't quite give you want you expect
My code has a buttload of functions already I'm trying to find something that doesn't need functions (for now) so when I'm reviewing my code I wont need to go up and down to see what each functions does (I tend to forget ), but yours works perfecly for what I want but since I'm in a mood to work I search the web a little more and I found a little something

Here's what I wrote based on my findings:

Code: Select all

--line being a variable holding the line's content
local count=1
char={}
string.gsub(line,'%d', function(a) char[count]=a count=count+1 end)
Now all I need to do is to put this in a for loop to read all the lines in the file, I'll post back for future refrences in a few minutes (cuz I'm going swimming now )

I'll post the for loop in a few minutes.
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping

Ranguna259
Party member
Posts: 911
Joined: Tue Jun 18, 2013 10:58 pm
Location: I'm right next to you

### Re: File lines to table (lua question)

Heres the code, it's heavily commented so everyone can understand it, if not then don't hesitate to ask.

This code can only load files with the following format:

Code: Select all

number,number,number ... number,
The last number should always have a comma (,) at the end and it can have as many numbers(each composed of only one digit, 1=OK 11=NO) and as many lines as you want.
They can be totaly random, ex:

Code: Select all

1,0,1,0,1,
0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,
1,2,2,0,2,2,
1,4,1,3,5,7,5,
What this code does is it reads the lines from a text file and divides each line into numbers (each number can have more then one digit: 1,12,123...etc) into a table variable (data[no. of line][no. of char]), this code can be mostly used to load maps from files with the above format.

Code: Select all

chars=1 --Variable controlling the characters flow in the data table
lines=1 --Variable controlling the lines flow in the data table
data={} --Table holding all the lines and characters formed by: data[no. of line][no. of char]
file = assert(io.open('temp.txt'))
for line in file:lines() do
data[lines]={} --Creats a new table for the line
string.gsub(line,'%d,', --'%d,' means everytime it finds a number followed by a ','
function(a) --That number and the comma are stored in variable a
string.gsub(a,'%d', --Everytime it finds a number (%d = digit)
function(b) --Stores the number in variable b
data[lines][chars]=b --Stores the number inside variable b in the table
chars=chars+1 --Adds one to the variable controlling the characters flow in the data table
end
)
end
)
chars=1 --Reverts the char count
lines=lines+1 --Adds one to the variable controlling the lines flow in the data table
end

--debugger
for a=1,#data do
for b=1,#data[a] do
print(data[a][b])
end
print(unpack(data[a]))
end

(You can remove the debugger code)
(
EDIT: the data table holds STRING value and NOT numeric value, so when you want call it in you code you do ex:
if data[1][1]=='1'