How Does the any Method Work in Groovy?

Ant's picture Ant's · Dec 11, 2011 · Viewed 8.3k times · Source

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)

  1. How does the code [*n..1,n] produce [4, 3, 2, 1, 4]?

  2. 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?

Answer

Dave Newton picture Dave Newton · Dec 11, 2011

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.