Given a string string
, what is the fastest/most-efficient way to count lines therein? Will accept best answers for any flavour of Rebol. I've been working under the assumption that the parse [some [thru]]
combination was the fastest way to traverse a string, but then I don't know that for certain, hence turning to SO:
count-lines: func [string [string!] /local count][
parse/all string [
(count: 1) some [thru newline (count: count + 1)]
]
count
]
Or:
count-lines: func [string [string!] /local count][
count: 0
until [
count: count + 1
not string: find/tail string newline
]
count
]
And how about counters? How efficient is repeat?
count-lines: func [string [string!]][
repeat count length? string [
unless string: find/tail string newline [
break/return count
]
]
]
Update: line count goes by the Text Editor principle:
An empty document still has a line count of one. So:
>> count-lines ""
== 1
>> count-lines "^/"
== 2
count-lines: func [
str
/local sort-str ][
sort-str: sort join str "^/"
1 + subtract index? find/last sort-str "^/" index? find sort-str "^/"
]
Enhanced PARSE version, as suggested by BrianH:
i: 1 ; add one as TextMate
parse text [any [thru newline (++ i)]]
print i
Here's the best simple non-parse
version I can think of:
count-lines: function [text [string!]] [
i: 1
find-all text newline [++ i]
i
]
It uses function
and ++
from more recent versions of Rebol, and find-all
from either R3 or R2/Forward. You could look at the source of find-all
and inline what you find and optimize, but situations like this are exactly what we wrote find-all
for, so why not use it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With