History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: GROOVY-2419
Type: New Feature New Feature
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Paul King
Reporter: Paul King
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
groovy

Provide a collectAll() method for lists (WAS: Provide a 'SpreadAllDot' operator)

Created: 19/Dec/07 03:48 AM   Updated: 03/Jan/08 05:46 AM
Component/s: None
Affects Version/s: 1.5, 1.5.1
Fix Version/s: 1.5.2

Time Tracking:
Not Specified


 Description  « Hide
Currently we have list*.method() that invokes the method on all items in the list.
It would be useful to also support list**.method() that invokes the method on all items in the list and recursively for any lists within the list.
def animalLists= [["ant", "mouse", "elephant"], ["deer", "monkey"]]
assert animalLists.size() == 2
assert animalLists*.size() == [3, 2]
assert animalLists**.size() == [[3, 5, 8], [4, 6]]


 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Guillaume Laforge - 19/Dec/07 04:42 AM
Interesting idea.
Do you think it should be a new notation, or in this case, wouldn't a method taking a closure be enough?
Say, something like collection.recurse { it.method() }

Paul King - 19/Dec/07 02:10 PM
I guess I was thinking about the shortened form to augment Groovy's GPath notation. E.g., considering GROOVY-2387, we removed a layer of magical unwrapping, so now the example is longer to type. In that example, the last line would go from:
assert [5 * 1499, 499, 4 * 499] == invoices.items.collect{ it*.total() }.flatten()

to:

assert [5 * 1499, 499, 4 * 499] == invoices.items**.total().flatten()

which would look nicer. But if people think it is confusing or if it turms out too hard to implement, then the longer form is also a possibility. Perhaps a Collection.collectAll{ closure } or as per your suggestion.


Guillaume Laforge - 19/Dec/07 02:21 PM
The double star is interesting, a method is easier to implement and doesn't require IDE developers to catch up
I'm not really sold on either of these approaches.
I'd be happy to have some more feedback from others as well.

Paul King - 20/Dec/07 06:48 PM
OK, I will have a bit more of a think about how to present the best possible case for it and then we can decide whether to dump the idea or not. It is meant to mimic the "node.**.xx" operator available for XML operations.

Paul King - 03/Jan/08 05:12 AM
What about just a collectAll method for now?
We could always add the ** later if we find it truly useful:
def animalLists= [["ant", "mouse", "elephant"], ["deer", "monkey"]]
assert animalLists*.size() == [3, 2]
assert animalLists.collect{ it.size() } == [3, 2]
assert animalLists.collectAll{ it.size() } == [[3, 5, 8], [4, 6]]
// assert animalLists**.size() == [[3, 5, 8], [4, 6]] // potential future enhancement

Guillaume Laforge - 03/Jan/08 05:18 AM
Yeah, collectAll() will do for now.