I would like to iterate over a large file line by line. I would also like to increment a counter for each line while doing so. I tried the following without success.
import strutils
for i, line in pairs("somefile.txt".lines):
echo i, line
That results in an error. Are pairs() only useful to generate an index for seqs and sets?
I'm looking for an idiomatic way of iterating over a file line by line while also keeping track of the line number.
The issue you're having is that lines itself is an iterator and pairs is as well. You can't combine iterators in this way. Either you need to read the file first, split it by lines and then use pairs on the resulting seq[string] like
import strutils
let lines = readFile("sometext.txt").splitLines()
for i, line in pairs(lines):
echo i, line
but this is inefficient as it first parses the file, then runs over it again to split the lines and finally runs over it a third time for your loop.
Another way is to use the lines iterator and count the lines yourself:
import strutils
var i = 0
for line in lines("sometext.txt"):
echo i, line
inc i
but of course that's a bit annoying.
Finally, which is probably the best option in this case, you can use std / enumerate:
https://nim-lang.org/docs/enumerate.html
like so:
import std / [strutils, enumerate]
for i, line in enumerate(lines("sometext.txt")):
echo i, line
to achieve what you intended initially. enumerate is a macro that generates code that is similar to the second option.
I did not know about enumerate. TIL.
Thank you!