File lines to table (lua question)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
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)

Post by Ranguna259 »

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

So can someone please help me on loading lines into arrays (bidimensional)

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

Check out my twitter.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: File lines to table (lua question)

Post by raidho36 »

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.
User avatar
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)

Post by Ranguna259 »

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 :D

Check out my twitter.
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: File lines to table (lua question)

Post by raidho36 »

You can try using foreach loop with string.gsub function.
User avatar
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)

Post by Ranguna259 »

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 :D

Check out my twitter.
User avatar
Omnivore
Prole
Posts: 18
Joined: Fri Jun 28, 2013 12:51 am
Location: West Coast

Re: File lines to table (lua question)

Post by Omnivore »

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
User avatar
MPQC
Citizen
Posts: 65
Joined: Fri Jun 28, 2013 2:45 pm

Re: File lines to table (lua question)

Post by MPQC »

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.
User avatar
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)

Post by Ranguna259 »

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 :crazy: ), 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 :megagrin: )

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 :D

Check out my twitter.
User avatar
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)

Post by Ranguna259 »

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'
instead of
if data[1][1]==1
)

You can all use this code to do whatevs you want, put it in a function if you like, it's yours :awesome:
Thanks for all the help people specialy to raidho36 for enlightning me on the string.gsub function :ultraglee:
(if you don't want to convert my code to a function or you just don't like it then you should check out Omnivore's or MPQC's function)
LoveDebug- A library that will help you debug your game with an on-screen fully interactive lua console, you can even do code hotswapping :D

Check out my twitter.
Post Reply

Who is online

Users browsing this forum: slime and 7 guests