This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Balthamel's profile picture

Write all lines in a file to a table.

Started by Balthamel, 23 July 2015 - 02:10 AM
Balthamel #1
Posted 23 July 2015 - 04:10 AM
I want to write each line in a file into a table, but i want to write the strings into the key and set the value to true.

I have

local junkFile = io.open("junk","r")
repeat
junkItems[junkFile.read("*line")] = true
until

but i can't see where to go from here i want it like this so i can use

if junkItems[string] then
as this will operate a lot faster than using any loop to check all the values and the table will be built only once and checked hundreds of times per run of the script.
I just can't work out how to stop the loop at the end of the file without writing junkItems[nil]=true and crashing.
Edited on 23 July 2015 - 02:10 AM
KingofGamesYami #2
Posted 23 July 2015 - 04:25 AM

local junkFile = io.open("junk","r")
repeat
  junkItems[junkFile.read("*line") or 'somerandomauththing'] = true
until junkItems[ 'somerandomauththing' ]

Or


local junkItems = {}
for line in io.lines( "junk" ) do
  junkItems[ line ] = true
end
Edited on 23 July 2015 - 02:29 AM
Balthamel #3
Posted 23 July 2015 - 04:30 AM
Thankyou
Grim Reaper #4
Posted 23 July 2015 - 04:34 AM

local junkFile = io.open("junk","r")
repeat
  junkItems[junkFile.read("*line") or 'somerandomauththing'] = true
until junkItems[ 'somerandomauththing' ]

Instead of using a special key to check if the file has been completely read, you could do the following:

-- Returns a table containing the contents of the file
-- at the given path.
--      @param path The path of the file to read.
--      @return table (or nil if bad path) with format: lines[line_as_key] = true
function getLinesInKeys(path)
    local fileHandle = fs.open(path, 'r')

    -- Validate handle.
    if not fileHandle then
        return
    end

    local fileContents = fileHandle.readAll()
    fileHandle.close()


    local lines = {}

    for line in fileContents:gmatch("[^\n]+") do
        lines[line] = true
    end

    return lines
end
It's a little more verbose, but this way you don't have to worry about having a line trigger the end condition.
MKlegoman357 #5
Posted 23 July 2015 - 05:49 AM
Instead of using a special key to check if the file has been completely read, you could do the following:

-- Returns a table containing the contents of the file
-- at the given path.
--      @param path The path of the file to read.
--      @return table (or nil if bad path) with format: lines[line_as_key] = true
function getLinesInKeys(path)
    local fileHandle = fs.open(path, 'r')

    -- Validate handle.
    if not fileHandle then
        return
    end

    local fileContents = fileHandle.readAll()
    fileHandle.close()


    local lines = {}

    for line in fileContents:gmatch("[^\n]+") do
        lines[line] = true
    end

    return lines
end
It's a little more verbose, but this way you don't have to worry about having a line trigger the end condition.

The fs API has built-in capabilities of reading the file line by line:


local lines = {}
local file = fs.open("file.txt", "r")

for line in file.readLine do
  lines[line] = true
end

file.close()
Balthamel #6
Posted 23 July 2015 - 06:49 AM
That is nice. Thanks.