Thursday, April 3, 2008

a groovy way to count number of lines

Groovy is nice to solve small problems (which usually will never pop up; but may!)

Note: The second example using eachLine() on a text file is the same file i used for my Automatic Resource Management (ARM) blocks example.


/*
this
is
a
string
*/
def str = """this
is
a
string
"""
int num = 0;
str.each { if(it == '\n') num++; }
println num // 4
/**
Doug Lea
Josh Bloch
Bob Lee
**/
num = 0;
new File("names.txt").eachLine { num++ }
println num; // 3


So that's it! 1 line of code to actually count the lines! the other 2 are just initialization and output!

5 comments:

Jim LoVerde said...

Yes, but wouldn't it have been nicer if they didn't deprecate the use of inject on File? Then you could do:

println new File("names.txt").inject(0) { num, l -> num++ }

Everything nice neat and tidy on a single line without needing to declare a variable

Robert O'Connor said...

That's not a bad idea :-x

Jim LoVerde said...

After opening a JIRA issue on this, I was greeting by none other than Guillaume with this response for how to do it:

println new File("names.txt").newReader().iterator().inject(0) { num, l -> num++ }

And there you go, no more need to define a variable.

Robert O'Connor said...

Jim, AWESOME!

Chim said...

couldn't figure for a while why this wasn't working for me, then noticed the num++ (return current value then increment)

changing it to ++num (increment then return) gave me the right count
num + 1 also works

Something must have changed between 2008 and 21012 :D


println new File("names.txt").newReader().iterator().inject(0) { num, l -> num++ }

OR

println new File("names.txt").newReader().iterator().inject(0) { num, l -> num + 1 }

I prefer the second alternative (num + 1) it's clearer that the closure variable isn't being modified itself but that the return is fed in to the next iteration.