I came across this bit of code:
n = args[0] as Long
[*n..1, n].any{ println ' '*it + '*'*(n - ~n - it*2) }
It's used for printing a tree form of structure. Like this:
*
***
*****
*******
*
(for n
=4)
How does the code [*n..1,n]
produce [4, 3, 2, 1, 4]
?
How does any
method works here? The Doc doesn't help me much. What is a predictive that can be passed to any
(as mentioned in Doc's)?
Whats the use of any
and how its handled in this case?
Q1a: *
"unpacks" an array. ..
creates a range. []
creates a collection.
Q1b: *n..1
unpacks [4,3,2,1] into its individual parts.
Q1c: [4,3,2,1,n]
== [4,3,2,1,4]
Q2: I don't know why any
was used here; each
works just as well, and makes more sense in context. any
does loop over the connection, so the println
side-effect functions as intended.
Normally any
would be used to determine if any collection elements met a criteria, for example:
[*n..1,n].any { it > 10 } // Returns false, no elements are > 10
[*n..1,n].any { it == 3 } // Returns true, because at least one element is 3
The last statement of the closure is used to determine if each item meets the criteria. println
returns null, so any
will return false. The value is unused and discarded.
The only reason I can think of that someone might have used any
is to avoid seeing the return value of each
in the console. each
returns the original collection.
1) n..1
is called a range literal, it creates a groovy.lang.Range
object that decrements by 1 from n
to 1
. This is then merged into the surrounding list context using the "Spread operator (*)"
2) the any
method is defined in DefaultGroovyMethods
and it is a predicate function that returns true if an element in a collection satisfies the supplied predicate closure. In this example, the code doesn't check the return value, so original other could have produced the same output using an each
call instead.
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