For minimum allocations, it's better to return a Vector of Vectors instead of a Matrix, and use data[i] as a row instead of data[i,:]. If a Matrix is strictly necessary, you'll need a simple conversion like mapreduce(permutedims, vcat, data) to get a Matrix.
So, build the Vectors directly from lines of the file and later append ""s as required.
function build_array(file)
data = split.(readlines(file))
N = maximum(length, data)
for d in data
for j = 1:N-length(d)
push!(d, "")
end
end
data
end
Using the following as input text file:
Scanning text file for
up to N words on each line,
filling array with columns
and rows of words in Julia.
The number of words isn't
known in advance.
The output will look like this:
build_array("input.txt")
6-element Vector{Vector{SubString{String}}}:
["Scanning", "text", "file", "for", "", "", ""]
["up", "to", "N", "words", "on", "each", "line,"]
["filling", "array", "with", "columns", "", "", ""]
["and", "rows", "of", "words", "in", "Julia.", ""]
["The", "number", "of", "words", "isn't", "", ""]
["known", "in", "advance.", "", "", "", ""]
And if used mapreduce(permutedims, vcat, data), you'll get:
6×7 Matrix{SubString{String}}:
"Scanning" "text" "file" "for" "" "" ""
"up" "to" "N" "words" "on" "each" "line,"
"filling" "array" "with" "columns" "" "" ""
"and" "rows" "of" "words" "in" "Julia." ""
"The" "number" "of" "words" "isn't" "" ""
"known" "in" "advance." "" "" "" ""