SlideShare a Scribd company logo
Groovy Collection API
Trygve Amundsen, Kodemaker
basics
groovy collections
•
•
•
•
•
•
•

Java Collection (List, Map, Set mfl.)
Array
String
Regexp
Iterable
CharSequence
Object!

assert "string".collect { it } == ['s','t','r','i','n','g']
assert 42.collect { it } == [42]

// string
notation, lists
def emptyList = []
assert [] instanceof ArrayList
def list = [1,2,3]
assert list[1..-1] == [2,3]
assert list[-3..-2] == [1,2]
assert list[2..1] == [3,2]
notation, maps
def emptyMap = [:]
assert [:] instanceof LinkedHashMap // predictable order
assert [a:1, b:2] == ['a':1, 'b':2]
method(a:1, b:2)

// illusion of named parameters
ranges are lists
assert (1..3) == [1,2,3]
assert (1..<3) == [1,2]

assert (1..3) instanceof IntRange // groovy.lang
assert (1..3) instanceof List
notation, list operators
assert
assert
assert
assert

[1,2] << 3 == [1,2,3]
// leftShift()
[1,2]+3 == [1,2,3]
// plus()
[1,2]+[3,4] == [1,2,3,4]
[1,2,3]-[3,4] == [1,2]
// minus()
notation, spread operator
assert ["a","b","1"]*.isNumber() == [false,false,true]
assert ["a","b","1"].number == [false,false,true]
basics, api
each
[1,2,3].each { println it}
[1,2,3].each { item -> println item }

[1,2,3].eachWithIndex { item, i -> println "index ${i} contains ${item}" }
[1,2,3].reverseEach { println it }
find (filters)
assert [1,2,3].findAll { it % 2 } == [1,3]
assert [1,2,3].find { it % 2 } == 1

assert [1,2,3].findIndexValues { it %2 } == [0,2]
collect (map)
assert [1,2,3].collect { it * it } == [1,4,9]

assert [1,[2,3],4].collectNested { it*it } == [1,[4,9],16]
assert [1,2,3].collectEntries { ['k' +it, it] } == [k1:1,k2:2,k3:3]
method returns
item content
collect
collectEntries
collectNested

Object

sort
groupBy

findAll
unique
tail
drop/take

stack

push/pop

max, min, sum, count
join
inject

Collection

multiple items

one item

each
eachWithIndex
reverseEach
find
head
first/last

changed

countBy
findResults
collectMany
split

plus
minus
intersect

subsequences
permutations
combinations

set

boolean

unchanged
changed

number of items

unchanged

any
every
reducers
assert [1,2,3].max() == 3
assert [1,2,3].min() == 1
assert [1,2,3].sum() == 6
assert [1,2,3].max{ -it } == 1
assert [1,2,3].max{ a,b-> b<=>a } == 1
reducers, cont’d
assert [1,2,3].any{ it > 3 } == false
assert [1,2,3].every{ it < 4 } == true

assert [1,2,3].join(";") == "1;2;3"
reducers, inject
assert [1,2,3].inject(0)
{ acc, val -> acc+val } == 6
assert [1,2,3].inject("0") { acc, val -> acc+val } == "0123"
assert [1,2,3].inject([]) { acc, val -> acc+val } == [1,2,3]
assert [a:1,b:2].inject(0) { acc, key, val -> acc+val } == 3
inject -> reduce
Object.metaClass.reduce = {initial, closure->
delegate.inject(initial, closure)
}
[1,2,3].reduce(0){acc,val->acc+val}
useful methods
groupBy, countBy

assert [1,2,3].groupBy{it < 2 ? 'small' : 'big'} == [small:[1], big:[2,3]]
assert [1,2,3].countBy{it < 2 ? 'small' : 'big'} == [small:1,
big:2]
set operations
assert [1,2]+3 == [1,2,3]
assert [1,2]+[3,4] == [1,2,3,4]
assert [1,2].plus([3,4]) == [1,2,3,4]
assert [1,2,3]-3 == [1,2]
assert [1,2,3]-[2,3] == [1]
assert [1,2,3].minus([2,3]) == [1]
assert [1,2,3].intersect([3,4]) == [3]
assert [1,2,3].disjoint([4,5]) == true
assert [1,2,3].subsequences() == [[3], [1, 2, 3], [1], [2], [2, 3], [1, 3], [1, 2]] as Set
assert [1,2,3].permutations() == [[1, 2, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2]] as Set
assert [[1,2],[3,4]].combinations() == [[1, 3], [2, 3], [1, 4], [2, 4]]
Nested Collections

assert [1,[2,3],4].flatten() == [1,2,3,4]
assert [1,[2,3],4].collectNested { it+10 } == [11,[12,13],14]
assert [['a','b'], [1,2]].transpose() == [['a',1],['b',2]]
functional style
assert [1,2,3].head() == 1
assert [1,2,3].tail() == [2,3]
assert [1,2,3].first() == 1
assert [1,2,3].last() == 3
assert [1,2,3].take(2) == [1,2]
assert [1,2,3].drop(2) == [3]
assert [1,2,3].split { it<3 } == [[1,2],[3]]
list as stack
NOTE: mutates!

def list = [1,2,3]
list.push(4)
assert list == [1,2,3,4]
assert list.pop() == 4
assert list == [1,2,3]
findResults
assert [1,2,3].findResults { it > 1 ? it*it : null } == [4,9]

[1,2,3].findResults { it > 1 ? it*it : null }

is identical to
[1,2,3].findAll { it > 1 }
.collect { it*it }
Other, possibly useful methods

assert [1,2,3].collectMany { [it**2, it**3] } == [1,1,4,8,9,27]
map withDefault
def newMap = [:].withDefault { [] }
[a:1,b:2,c:2].each { key, val ->
newMap[val] << key
}
assert newMap == [1:['a'], 2:['b','c']]
mutability
•
•
•
•

all methods return new collections/objects

•

a few exceptions exist, such as push/pop and sort(boolean mutate)

objects and collections are generally mutable
use asImmutable(), asSynchronized() for multithreading
or better: use gpars (included in groovy jdk)

•

(that’s a different talk - coming up on groovy meetup!)
doc & src
Groovy JDK doc
Groovy JDK doc
DefaultGroovyMethods
real-world example
params.findAll { key, val ->
// filtrer kun diagnose-parametre
key.startsWith(paramPrefix+"diagnoser")
}.groupBy { key, val ->
// grupper på rader
key.substring(0,"diagnoser[0]".size())
}.findAll { rowKey, rowMap ->
// Fjern tomme rader
rowMap.any { key, val -> val && val != "null" }
}.inject([:]) { acc, key, val ->
// ungroup rader (tilbake til en map med parametre)
acc + val
}.collectEntries { key, val ->
// hent sykdomskode.id
if (key.endsWith('.sykdomskode') && val) {
[key+'.id', Sykdomskode.findByNr(val)?.id ?: ""]
} else {
[key, val]
}
}.sort {
it.key
}
more...
groovy.codehaus.org
meetup.com/Oslo-Groovy-Meetup
questions ?
Ubrukt
sample data
@EqualsAndHashCode @ToString class Person { def name, address, pets }
@EqualsAndHashCode @ToString class Address { def street, city }
enum Pet { CAT, DOG, BIRD, DUCK }
import static Pet.*
def persons = [
new Person(name:"Ole",
address:new Address(street:"Blindvn 1", city:"Oslo"),
pets:[BIRD, CAT]),
new Person(name:"Dole",
address:new Address(street:"Blindvn 2", city:"Oslo"),
pets:[DOG, CAT]),
new Person(name:"Doff",
address:new Address(street:"Strandvn 9", city:"Bergen"),
pets:[BIRD, DOG]),
]
assert persons.pets == [ [BIRD, CAT], [DOG, CAT], [BIRD, DOG]]
assert persons.pets.flatten().unique() == [BIRD, CAT, DOG]
assert persons.address.city.unique() == ["Oslo", "Bergen"]
real-world example
import org.ccil.cowan.tagsoup.Parser
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7')
def gdocHome = "http://groovy.codehaus.org/groovy-jdk/"
def gdocs = ["java/lang": ["Object[]","Object"],
"java/util": ["Collection", "List", "Map"]]
gdocs.inject([:]) { agg, key, val ->
// create map of [class:url]
agg + val.collectEntries { [it, gdocHome + key+"/"+it+".html" ] }
}.collectEntries { className, url ->
// parse urls
def html = new XmlParser(new Parser()).parse(url)
[className, html.body.table[1].tr[1..-1].collect {
it.td[1].code.b.a.text()
}]
}
• gå dypt i utvalgte kall, ex
•
•
•
•

groupBy
inject
findResult: find + transform
nested collections: collectNested
Groovy Collection Jdk Doc
• Object
• Object[]
• Collection
• Map
• List
• Set
Basic collection types
assert
assert
assert
assert
assert

[] instanceof ArrayList
// (java.util)
[:] instanceof LinkedHashMap
// predictable order
([] as Set) instanceof HashSet
(1..3) instanceof IntRange
// groovy.lang
(1..3) instanceof List

More Related Content

What's hot

Palestra sobre Collections com Python
Palestra sobre Collections com PythonPalestra sobre Collections com Python
Palestra sobre Collections com Python
pugpe
 
Clustering com numpy e cython
Clustering com numpy e cythonClustering com numpy e cython
Clustering com numpy e cython
Anderson Dantas
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察
Tsuyoshi Yamamoto
 

What's hot (19)

Groovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトークGroovy ネタ NGK 忘年会2009 ライトニングトーク
Groovy ネタ NGK 忘年会2009 ライトニングトーク
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
Building Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at StripeBuilding Real Time Systems on MongoDB Using the Oplog at Stripe
Building Real Time Systems on MongoDB Using the Oplog at Stripe
 
MongoDB With Style
MongoDB With StyleMongoDB With Style
MongoDB With Style
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Palestra sobre Collections com Python
Palestra sobre Collections com PythonPalestra sobre Collections com Python
Palestra sobre Collections com Python
 
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
Swift - 혼자 공부하면 분명히 안할테니까 같이 공부하기
 
Clustering com numpy e cython
Clustering com numpy e cythonClustering com numpy e cython
Clustering com numpy e cython
 
Python 내장 함수
Python 내장 함수Python 내장 함수
Python 내장 함수
 
Oh Composable World!
Oh Composable World!Oh Composable World!
Oh Composable World!
 
PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007PHP and MySQL Tips and tricks, DC 2007
PHP and MySQL Tips and tricks, DC 2007
 
Oop lecture9 13
Oop lecture9 13Oop lecture9 13
Oop lecture9 13
 
RxSwift 시작하기
RxSwift 시작하기RxSwift 시작하기
RxSwift 시작하기
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Promise
PromisePromise
Promise
 
Advanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part IIAdvanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part II
 
python高级内存管理
python高级内存管理python高级内存管理
python高级内存管理
 
Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察Jggug 2010 330 Grails 1.3 観察
Jggug 2010 330 Grails 1.3 観察
 
Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)Swift에서 꼬리재귀 사용기 (Tail Recursion)
Swift에서 꼬리재귀 사용기 (Tail Recursion)
 

Viewers also liked

Viewers also liked (20)

Working with Groovy Collections
Working with Groovy CollectionsWorking with Groovy Collections
Working with Groovy Collections
 
Grails custom tag lib
Grails custom tag libGrails custom tag lib
Grails custom tag lib
 
Grails internationalization-160524154831
Grails internationalization-160524154831Grails internationalization-160524154831
Grails internationalization-160524154831
 
G pars
G parsG pars
G pars
 
Bootcamp linux commands
Bootcamp linux commandsBootcamp linux commands
Bootcamp linux commands
 
Meta Programming in Groovy
Meta Programming in GroovyMeta Programming in Groovy
Meta Programming in Groovy
 
Groovy intro
Groovy introGroovy intro
Groovy intro
 
Groovy
GroovyGroovy
Groovy
 
Spring boot
Spring bootSpring boot
Spring boot
 
Twilio
TwilioTwilio
Twilio
 
Gorm
GormGorm
Gorm
 
Docker
DockerDocker
Docker
 
Introduction to mongo db
Introduction to mongo dbIntroduction to mongo db
Introduction to mongo db
 
Unit test-using-spock in Grails
Unit test-using-spock in GrailsUnit test-using-spock in Grails
Unit test-using-spock in Grails
 
Actors model in gpars
Actors model in gparsActors model in gpars
Actors model in gpars
 
MetaProgramming with Groovy
MetaProgramming with GroovyMetaProgramming with Groovy
MetaProgramming with Groovy
 
Java reflection
Java reflectionJava reflection
Java reflection
 
Grails services
Grails servicesGrails services
Grails services
 
Grails Controllers
Grails ControllersGrails Controllers
Grails Controllers
 
Grails with swagger
Grails with swaggerGrails with swagger
Grails with swagger
 

Similar to Groovy collection api

Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
PrinceGuru MS
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
timourian
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
aztack
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changes
hayato
 

Similar to Groovy collection api (20)

Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
 
Javascript
JavascriptJavascript
Javascript
 
Coscup2021-rust-toturial
Coscup2021-rust-toturialCoscup2021-rust-toturial
Coscup2021-rust-toturial
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
Groovy
GroovyGroovy
Groovy
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
8558537werr.pptx
8558537werr.pptx8558537werr.pptx
8558537werr.pptx
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
 
Introducción a Elixir
Introducción a ElixirIntroducción a Elixir
Introducción a Elixir
 
Underscore.js
Underscore.jsUnderscore.js
Underscore.js
 
[1062BPY12001] Data analysis with R / week 2
[1062BPY12001] Data analysis with R / week 2[1062BPY12001] Data analysis with R / week 2
[1062BPY12001] Data analysis with R / week 2
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Day 4a iteration and functions.pptx
Day 4a   iteration and functions.pptxDay 4a   iteration and functions.pptx
Day 4a iteration and functions.pptx
 
Clojure functions midje
Clojure functions midjeClojure functions midje
Clojure functions midje
 
ECMAScript 6 major changes
ECMAScript 6 major changesECMAScript 6 major changes
ECMAScript 6 major changes
 
Brief intro to clojure
Brief intro to clojureBrief intro to clojure
Brief intro to clojure
 

Recently uploaded

Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Peter Udo Diehl
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 

Recently uploaded (20)

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 

Groovy collection api

  • 1. Groovy Collection API Trygve Amundsen, Kodemaker
  • 3. groovy collections • • • • • • • Java Collection (List, Map, Set mfl.) Array String Regexp Iterable CharSequence Object! assert "string".collect { it } == ['s','t','r','i','n','g'] assert 42.collect { it } == [42] // string
  • 4. notation, lists def emptyList = [] assert [] instanceof ArrayList def list = [1,2,3] assert list[1..-1] == [2,3] assert list[-3..-2] == [1,2] assert list[2..1] == [3,2]
  • 5. notation, maps def emptyMap = [:] assert [:] instanceof LinkedHashMap // predictable order assert [a:1, b:2] == ['a':1, 'b':2] method(a:1, b:2) // illusion of named parameters
  • 6. ranges are lists assert (1..3) == [1,2,3] assert (1..<3) == [1,2] assert (1..3) instanceof IntRange // groovy.lang assert (1..3) instanceof List
  • 7. notation, list operators assert assert assert assert [1,2] << 3 == [1,2,3] // leftShift() [1,2]+3 == [1,2,3] // plus() [1,2]+[3,4] == [1,2,3,4] [1,2,3]-[3,4] == [1,2] // minus()
  • 8. notation, spread operator assert ["a","b","1"]*.isNumber() == [false,false,true] assert ["a","b","1"].number == [false,false,true]
  • 10. each [1,2,3].each { println it} [1,2,3].each { item -> println item } [1,2,3].eachWithIndex { item, i -> println "index ${i} contains ${item}" } [1,2,3].reverseEach { println it }
  • 11. find (filters) assert [1,2,3].findAll { it % 2 } == [1,3] assert [1,2,3].find { it % 2 } == 1 assert [1,2,3].findIndexValues { it %2 } == [0,2]
  • 12. collect (map) assert [1,2,3].collect { it * it } == [1,4,9] assert [1,[2,3],4].collectNested { it*it } == [1,[4,9],16] assert [1,2,3].collectEntries { ['k' +it, it] } == [k1:1,k2:2,k3:3]
  • 13. method returns item content collect collectEntries collectNested Object sort groupBy findAll unique tail drop/take stack push/pop max, min, sum, count join inject Collection multiple items one item each eachWithIndex reverseEach find head first/last changed countBy findResults collectMany split plus minus intersect subsequences permutations combinations set boolean unchanged changed number of items unchanged any every
  • 14. reducers assert [1,2,3].max() == 3 assert [1,2,3].min() == 1 assert [1,2,3].sum() == 6 assert [1,2,3].max{ -it } == 1 assert [1,2,3].max{ a,b-> b<=>a } == 1
  • 15. reducers, cont’d assert [1,2,3].any{ it > 3 } == false assert [1,2,3].every{ it < 4 } == true assert [1,2,3].join(";") == "1;2;3"
  • 16. reducers, inject assert [1,2,3].inject(0) { acc, val -> acc+val } == 6 assert [1,2,3].inject("0") { acc, val -> acc+val } == "0123" assert [1,2,3].inject([]) { acc, val -> acc+val } == [1,2,3] assert [a:1,b:2].inject(0) { acc, key, val -> acc+val } == 3
  • 17. inject -> reduce Object.metaClass.reduce = {initial, closure-> delegate.inject(initial, closure) } [1,2,3].reduce(0){acc,val->acc+val}
  • 19. groupBy, countBy assert [1,2,3].groupBy{it < 2 ? 'small' : 'big'} == [small:[1], big:[2,3]] assert [1,2,3].countBy{it < 2 ? 'small' : 'big'} == [small:1, big:2]
  • 20. set operations assert [1,2]+3 == [1,2,3] assert [1,2]+[3,4] == [1,2,3,4] assert [1,2].plus([3,4]) == [1,2,3,4] assert [1,2,3]-3 == [1,2] assert [1,2,3]-[2,3] == [1] assert [1,2,3].minus([2,3]) == [1] assert [1,2,3].intersect([3,4]) == [3] assert [1,2,3].disjoint([4,5]) == true assert [1,2,3].subsequences() == [[3], [1, 2, 3], [1], [2], [2, 3], [1, 3], [1, 2]] as Set assert [1,2,3].permutations() == [[1, 2, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2]] as Set assert [[1,2],[3,4]].combinations() == [[1, 3], [2, 3], [1, 4], [2, 4]]
  • 21. Nested Collections assert [1,[2,3],4].flatten() == [1,2,3,4] assert [1,[2,3],4].collectNested { it+10 } == [11,[12,13],14] assert [['a','b'], [1,2]].transpose() == [['a',1],['b',2]]
  • 22. functional style assert [1,2,3].head() == 1 assert [1,2,3].tail() == [2,3] assert [1,2,3].first() == 1 assert [1,2,3].last() == 3 assert [1,2,3].take(2) == [1,2] assert [1,2,3].drop(2) == [3] assert [1,2,3].split { it<3 } == [[1,2],[3]]
  • 23. list as stack NOTE: mutates! def list = [1,2,3] list.push(4) assert list == [1,2,3,4] assert list.pop() == 4 assert list == [1,2,3]
  • 24. findResults assert [1,2,3].findResults { it > 1 ? it*it : null } == [4,9] [1,2,3].findResults { it > 1 ? it*it : null } is identical to [1,2,3].findAll { it > 1 } .collect { it*it }
  • 25. Other, possibly useful methods assert [1,2,3].collectMany { [it**2, it**3] } == [1,1,4,8,9,27]
  • 26. map withDefault def newMap = [:].withDefault { [] } [a:1,b:2,c:2].each { key, val -> newMap[val] << key } assert newMap == [1:['a'], 2:['b','c']]
  • 27. mutability • • • • all methods return new collections/objects • a few exceptions exist, such as push/pop and sort(boolean mutate) objects and collections are generally mutable use asImmutable(), asSynchronized() for multithreading or better: use gpars (included in groovy jdk) • (that’s a different talk - coming up on groovy meetup!)
  • 32. real-world example params.findAll { key, val -> // filtrer kun diagnose-parametre key.startsWith(paramPrefix+"diagnoser") }.groupBy { key, val -> // grupper på rader key.substring(0,"diagnoser[0]".size()) }.findAll { rowKey, rowMap -> // Fjern tomme rader rowMap.any { key, val -> val && val != "null" } }.inject([:]) { acc, key, val -> // ungroup rader (tilbake til en map med parametre) acc + val }.collectEntries { key, val -> // hent sykdomskode.id if (key.endsWith('.sykdomskode') && val) { [key+'.id', Sykdomskode.findByNr(val)?.id ?: ""] } else { [key, val] } }.sort { it.key }
  • 36. sample data @EqualsAndHashCode @ToString class Person { def name, address, pets } @EqualsAndHashCode @ToString class Address { def street, city } enum Pet { CAT, DOG, BIRD, DUCK } import static Pet.* def persons = [ new Person(name:"Ole", address:new Address(street:"Blindvn 1", city:"Oslo"), pets:[BIRD, CAT]), new Person(name:"Dole", address:new Address(street:"Blindvn 2", city:"Oslo"), pets:[DOG, CAT]), new Person(name:"Doff", address:new Address(street:"Strandvn 9", city:"Bergen"), pets:[BIRD, DOG]), ] assert persons.pets == [ [BIRD, CAT], [DOG, CAT], [BIRD, DOG]] assert persons.pets.flatten().unique() == [BIRD, CAT, DOG] assert persons.address.city.unique() == ["Oslo", "Bergen"]
  • 37. real-world example import org.ccil.cowan.tagsoup.Parser @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7') def gdocHome = "http://groovy.codehaus.org/groovy-jdk/" def gdocs = ["java/lang": ["Object[]","Object"], "java/util": ["Collection", "List", "Map"]] gdocs.inject([:]) { agg, key, val -> // create map of [class:url] agg + val.collectEntries { [it, gdocHome + key+"/"+it+".html" ] } }.collectEntries { className, url -> // parse urls def html = new XmlParser(new Parser()).parse(url) [className, html.body.table[1].tr[1..-1].collect { it.td[1].code.b.a.text() }] }
  • 38. • gå dypt i utvalgte kall, ex • • • • groupBy inject findResult: find + transform nested collections: collectNested
  • 39. Groovy Collection Jdk Doc • Object • Object[] • Collection • Map • List • Set
  • 40. Basic collection types assert assert assert assert assert [] instanceof ArrayList // (java.util) [:] instanceof LinkedHashMap // predictable order ([] as Set) instanceof HashSet (1..3) instanceof IntRange // groovy.lang (1..3) instanceof List

Editor's Notes

  1. merk strings og charsequence
  2. Bra for named parameters!
  3. Some say thats bad, wtf
  4. leftShift == putte inn i - operatoren
  5. Ta litt tid hero - isNumber er en String operasjon (ikke en collection operasjon) - Collections har ikke properties, så variant 2 representerer ikke noen tvetydigheter
  6. Trofast, første møtet Returnerer ingenting (jo, umodifisert collection) Bare en vanlig for-loop, en blindvei på veien mot funksjonell nirvana Avhengig av side-effekter for å utføre noe.
  7. find burde kanskje hete findFirst burde vært en alias for filter - det er det ikke
  8. Heter map i mange språk, men collect passer godt i en java-verden map henviser jo til noe helt annet Veldig nyttig: hvis man vil ha map: bruk collectEntries, returner en array [key, val] tygg på navnet: godt navn
  9. Fra 30000 fot: bilde!!
  10. Reducers - noen kaller det foldLeft, silly :) (alle disse tar også transformer/comparator for ikke-standard sammenligning)
  11. Dette er lett ;) Burde hett reduce. foldLeft i mange språk. foldRight Mangler i groovy. Ta litt tid: 1) initial value 2) to understand: closure returns next accumulator
  12. Bare mer komplisert. Hva gjør den nullen der? (indikerer at raden skal filtreres bort - ikke akkurat selvforklarende) Jeg nevner dette for det ikke står i doken
  13. Her er de fleste collection-metoder (+ noen fler) definert resten er i StringGroovyMethods