# Line feed by spaces

hello, can you tell me how to make a better function that performs line feeds by spaces, than what I did with my natural science education, i, j, l and += 1 ?

``````function feed_lines(str::String, l::Int)
chars = collect(str)
i = findfirst(' ', str)
j = 1
for (index, char) in pairs(chars)
if char == ' '
i = index
end
if j > l
chars[i] = '\n'
j = index - i
end
j += 1
end
return join(chars)
end
``````

although it seems not so bad

Could you explain what is the role of integer `l`?

In my limited understanding the following seems to produce similar results:

``````feed_lines2(str::String) = join(split(str),"\n")
``````
1 Like

this is line length, if line length > l then replace last space (which < l) to ‘\n’

Could you provide a minimum working example (MWE) to illustrate what it is supposed to do?

sure

``````julia> function feed_lines(str::String, l::Int)
chars = collect(str)
i = findfirst(' ', str)
j = 1
for (index, char) in pairs(chars)
if char == ' '
i = index
end
if j > l
chars[i] = '\n'
j = index - i
end
j += 1
end
return join(chars)
end
feed_lines (generic function with 1 method)

julia> feed_lines("""hello, can you tell me how to make a better function that performs line feeds by spaces, than what I did with my natural science education, i, j, l and += 1 ?""", 30) |> println

hello, can you tell me how to
make a better function that
performs line feeds by spaces,
than what I did with my
natural science education, i,
j, l and += 1 ?
``````
1 Like

Just an idea (not quite doing what you ask for):

``````julia> join(join.(Iterators.partition(s, 30) |> collect, ""), "\n") |> println
hello, can you tell me how to
make a better function that pe
rforms line feeds by spaces, t
han what I did with my natural
science education, i, j, l an
d += 1 ?
``````

where `s` is your example string.

(Do we have an efficient “word iterator” somewhere?)

2 Likes

This is rather compact:

``````julia> function feed_lines2(str, l)
line_breaks = findnext.(' ', str, l:l:length(str))
join([i in line_breaks ? '\n' : c for (i,c) in pairs(str)])
end
feed_lines2 (generic function with 1 method)

julia> feed_lines2("""hello, can you tell me how to make a better function that performs line feeds by spaces, than what I did with my natural science education, i, j, l and += 1 ?""", 30) |> println
hello, can you tell me how to
make a better function that performs
line feeds by spaces, than
what I did with my natural
science education, i, j, l and
+= 1 ?
``````

However, I think it will be (a bit) less efficient than your variant.

2 Likes

A version that uses `SubString` and also returns the number of rows printed:

``````function feed_lines3(str, n)
ix = [1; findall(' ', str); length(str)]
j1 = zero(ix)
j2 = zero(ix)
nr = 1
j1[1] = 1
for i in 2:length(ix)
if ix[i] - j1[nr] > n
j2[nr] = ix[i-1]
nr += 1
j1[nr] = ix[i-1] + 1
elseif i == length(ix)
j2[nr] = ix[end]
end
end
join(SubString.(str, view(j1,1:nr), view(j2,1:nr)), "\n"), nr
end

println(feed_lines3(str, 30)[1])
# result:
hello, can you tell me how to
make a better function that
performs line feeds by spaces,
than what I did with my
natural science education, i,
j, l and += 1 ?
``````

This version should be further optimized, as only one `j` array seems necessary.

2 Likes

FWIW, a simpler alternative and a bit faster:

``````function feed_lines4(str, n)
ix = [1; findall(' ', str); length(str)]
nx = length(ix)
j = 1;
s2 = ""
for i in 2:nx
if ix[i] - j > n
s2 = s2 * view(str,j:ix[i-1]) * "\n"
j = ix[i-1] + 1
elseif i == nx
s2 = s2 * view(str,j:ix[nx]) * "\n"
end
end
return s2
end

println(feed_lines4(str,30))
# result:
hello, can you tell me how to
make a better function that
performs line feeds by spaces,
than what I did with my
natural science education, i,
j, l and += 1 ?
``````
4 Likes

@stevengj, the `TextWrap.jl` package although more general seems for the OP example to be slower than the above solutions (maybe `~3x` when comparing using @time run multiple times).