Courses/CS 537/Summer 2008/Chapter 4. Collective Groovy datatypes

From CSULA CS Wiki
Jump to: navigation, search

Ranges

assert 0 .. 10 == 0 .. 10
// The "half range" operator is ..<
assert 0 ..< 10 == 0 .. 9
 
log = ''
// <<= means shift in from the right and then 
// assign back to the variable, like += .
(9 ..< 0).each{element -> log <<= element}
assert log.toString().reverse() == "123456789"
 
range = 0 .. 4
assert range[4] == 4
assert range[5] == null
assert range[0] == 0
assert range[-1] == 4
assert range[-5] == 0
// Throws an out-of-bounds exception.
// assert range[-6] == null
 
(0 .. 10).each{print it + " "} // prints: 0 1 2 3 4 5 6 7 8 9 10 
println '' + (0 .. 10).getClass() // prints: class groovy.lang.IntRange
println (0 .. 10).getClass() // prints: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Strange!
println (0 .. 10)  // prints: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
assert (0 .. 10) instanceof groovy.lang.IntRange
println (0 .. 10).getClass().getSimpleName() // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
(0.5 ..< 9.3).each{print it + " "} // prints: 0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 
println ''
println (0.5 ..< 9.3).getClass() // prints: [0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5]
println '' + (0.5 ..< 9.3).getClass() // prints: class groovy.lang.ObjectRange
assert (0.5 ..< 9.3) instanceof groovy.lang.ObjectRange

Lists

myList = ['a', 'b', 'c', 'd', 'e', 'f']
assert myList[0..2] == ['a', 'b', 'c']
assert myList[0, 2, 4] == ['a', 'c', 'e']
myList[0..2] = ['x', 'y', 'z']
assert myList == ['x', 'y', 'z', 'd', 'e', 'f']
myList[3 .. 5] = []
assert myList == ['x', 'y', 'z']
// myList is an ArrayList and can hold heterogeneous elements.
assert myList instanceof java.util.ArrayList
myList[1..1] = ['y', 1, 2]
assert myList ==  ['x', 'y', 1, 2, 'z']
 
myList = []
myList += 'a'
assert myList == ['a']
myList += ['b', 'c']
assert myList == ['a', 'b', 'c']
myList -= ['a', 'b', 'c']
assert myList == []
myList << 'a' << 'b'
assert myList == ['a', 'b']
assert myList * 2 == ['a', 'b', 'a', 'b']
(myList * 2).each{print it + ' '} // prints: a b a b 
 
// grep is filter. Can take a list or a closure.
println '\n' + (myList * 2).grep(['b']) // println: ['b', 'b']
[1, 2, 3].grep({it > 2}) // prints: [3]
 
// grep is a method of Object. It produces a Collection
assert 3.grep({it > 2}) == [3]
assert 3.grep({it < 2}) == []

Lots of List operations. For example:

assert [1, 2, 3].intersect([2, 3, 4]) == [2, 3]
 
// This is normally called filter. Similar to but not identical to grep.
assert [1, 2, 3].findAll{it < 3} == [1, 2]
 
// This is normally called map.
assert [1, 2, 3].collect{it * 2} == [2, 4, 6]
 
// This is normally called reduce.
// Find the product of the even list elements.
// Iterates through the list producing an accumulated result. 
// The initial value of the accumulated result is the argument to inject.
[2, 3, 4, 5, 6, 7].inject(1) {
    acc, item -> 
        print acc + ", " + item + " -> ";
        next = item % 2 == 0 ? item * acc : acc;  
        println next;  
        next // Note must return a value for next iteration.
    }
/* 
Produces
1, 2 -> 2
2, 3 -> 2
2, 4 -> 8
8, 5 -> 8
8, 6 -> 48
48, 7 -> 48
Result: 48
*/
 
// Can sort with default ordering or supply your own.
assert ['b', 'aa'].sort() == ['aa', 'b']
// If a comparator is supplied must satisfy java.util Interface Comparator,
// i.e., return negative, 0, or positive
assert ['b', 'aa'].sort({x, y -> x.length() <=> y.length()}) == ['b', 'aa']
assert ['b', 'aa'].sort({x-> x.length()}) == ['b', 'aa']
 
// Define zip. There are no tuples in Groovy. 
zip = {a, b -> 
 result = []
 0.upto(Math.min(a.size(), b.size())-1){index -> result << [a[index], b[index]]}
 result}
 
assert zip([1, 2, 3], [4, 5, 6, 7]) ==  [[1, 4], [2, 5], [3, 6]]
 
// Define zipWith. 
zipWith = {f, a, b -> 
 result = []
 0.upto(Math.min(a.size(), b.size())-1){index -> result << f(a[index], b[index])}
 result}
 
assert zipWith({x, y -> x + y}, [1, 2, 3], [4, 5, 6, 7]) ==  [5, 7, 9]

Maps

Maps are HashMaps with some convenience notation and a few added methods. (See p 112 - 116.)

// The empty map.
def myMap = [:]
assert myMap.isEmpty()
// "a" is taken to be a string. (I think that's a bad convention.)
myMap.a = 1
myMap['b'] = 2
a = 'c'
myMap[(a)] = 3
myMap.'d.e' = 4
assert myMap == ["a":1, "b":2, "c":3, "d.e":4]
assert myMap.a ==  myMap.'a'
assert myMap[a] == myMap['c']
assert myMap.get('b') == 2
// Can specify default values if the key is not in the map.
assert myMap.get('b', 5) == 2
assert myMap.get('f') == null
assert myMap.get('f', 6) == 6
 
 
collection = myMap.collect{entry -> [entry.key, entry.value]}
assert collection == [["a", 1], ["b", 2], ["c", 3], ["d.e", 4], ["f", 6]]
 
// Word count example
 
corpus =
"""
Look for the bare necessities
The simple bare necessities
Forget about your worries and your strife
I mean the bare necessities
Old Mother Nature's recipes
That bring the bare necessities of life
"""
 
wordFrequencies = [:]
corpus.tokenize().each { word ->
 wordFrequencies[word] = wordFrequencies.get(word, 0) + 1
}
wordList = wordFrequencies.keySet().toList().sort { wordFrequencies[it] }
 
// Only list words that appear more than once.
finalFrequencies = wordList.reverse().inject([:]) {
    intermediateFrequencies, word -> 
      if (wordFrequencies[word] > 1) 
            intermediateFrequencies[word] = wordFrequencies[word]
    intermediateFrequencies // Must return intermediateFrequencies 
  }
assert finalFrequencies == ["bare":4, "necessities":4, "the":3, "your":2]
Computer Science
Personal tools