//---------------------------------------------------------------------------------- simple = [ "this", "that", "the", "other" ] nested = [ "this", "that", [ "the", "other" ] ] assert nested.size() == 3 assert nested[2].size() == 2 flattenNestedToSimple = [ "this", "that", [ "the", "other" ] ].flatten() assert flattenNestedToSimple.size() == 4 //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- a = [ "quick", "brown", "fox" ] assert a.size() == 3 a = 'Why are you teasing me?'.split(' ') assert a == ["Why", "are", "you", "teasing", "me?"] removeLeadingSpaces = { it.trim() } nonBlankLines = { it } lines = ''' The boy stood on the burning deck, It was as hot as glass. '''.split('\n').collect(removeLeadingSpaces).findAll(nonBlankLines) assert lines == ["The boy stood on the burning deck,", "It was as hot as glass."] // initialiseListFromFileScript: lines = new File('mydata.txt').readLines() // processFileScript: new File('mydata.txt').eachLine{ // dosomething } //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- marbleColors = ['red', 'green', 'yellow'] assert marbleColors.join(', ') == 'red, green, yellow' def commify(items) { if (!items) return items def sepchar = items.find{ it =~ /,/ } ? '; ' : ', ' switch (items.size()) { case 1: return items[0] case 2: return items.join(' and ') } items[0..-2].join(sepchar) + sepchar + 'and ' + items[-1] } assert commify(marbleColors) == 'red, green, and yellow' lists = [ [ 'just one thing' ], [ 'Mutt', 'Jeff' ], 'Peter Paul Mary'.split(' '), [ 'To our parents', 'Mother Theresa', 'God' ], [ 'pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna' ], [ 'recycle tired, old phrases', 'ponder big, happy thoughts' ], [ 'recycle tired, old phrases', 'ponder big, happy thoughts', 'sleep and dream peacefully' ], ] expected = ''' just one thing Mutt and Jeff Peter, Paul, and Mary To our parents, Mother Theresa, and God pastrami, ham and cheese, peanut butter and jelly, and tuna recycle tired, old phrases and ponder big, happy thoughts recycle tired, old phrases; ponder big, happy thoughts; and sleep and dream peacefully ''' assert expected == '\n' + lists.collect{commify(it)}.join('\n') + '\n' //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // In Groovy, lists and arrays are more or less interchangeable // here is the example using lists people = ['Crosby', 'Stills', 'Nash'] assert people.size() == 3 people[3] = 'Young' assert people.size() == 4 assert people == ['Crosby', 'Stills', 'Nash', 'Young'] // to use arrays simply do 'people = peopleArray.toList()' at the start // and 'peopleArray = people as String[]' at the end // if you attempt to do extension on a Java array you will get an // ArrayIndexOutOfBoundsException - which is why Java has ArrayList et al //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // list to process people == ['Crosby', 'Stills', 'Nash', 'Young'] // helper startsWithCapital = { word -> word[0] in 'A'..'Z' } // various styles are possible for processing lists // closure style people.each { person -> assert startsWithCapital(person) } // for loop style for (person in people) { assert startsWithCapital(person) } // unixScriptToFindAllUsersStartingWithLetterA: all = 'who'.execute().text.replaceAll('\r', '').split('\n') all.grep(~/^a.*/).each{ println it } // printFileWithWordsReversedScript: new File('Pleac/src/SlowCat.groovy').eachLine{ line -> line.split(' ').each{ print it.reverse() } } a = [0.5, 3]; b = [0, 1] assert [a, b].flatten().collect{ it * 7 } == [3.5, 21, 0, 7] // above doesn't modify original arrays // instead use a = a.collect{ ... } //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // not relevant in Groovy since we have always references items = [] for (item in items) { // do something with item } //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- assert [ 1, 1, 2, 2, 3, 3, 3, 5 ].unique() == [ 1, 2, 3, 5 ] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- assert [ 1, 1, 2, 2, 3, 3, 3, 4, 5 ] - [ 1, 2, 4 ] == [3, 3, 3, 5] assert [ 1, 1, 2, 2, 3, 3, 3, 4, 5 ].unique() - [ 1, 2, 4 ] == [3, 5] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- a = [1, 3, 5, 6, 7, 8] b = [2, 3, 5, 7, 9] // intersection assert a.intersect(b) == [3, 5, 7] // union assert (a + b).unique().sort() == [1, 2, 3, 5, 6, 7, 8, 9] // difference assert (a - b) == [1, 6, 8] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- members = [ "Time", "Flies" ] initiates = [ "An", "Arrow" ] members += initiates assert members == ["Time", "Flies", "An", "Arrow"] members.add(2, "Like") assert members == ["Time", "Flies", "Like", "An", "Arrow"] members[0] = "Fruit" members[3..4] = ["A", "Banana"] assert members == ["Fruit", "Flies", "Like", "A", "Banana"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- items = ["the", "quick", "brown", "fox"] assert items.reverse() == ["fox", "brown", "quick", "the"] firstLetters = [] items.reverseEach{ firstLetters += it[0] } assert firstLetters.join() == 'fbqt' descending = items.sort().reverse() assert descending == ["the", "quick", "fox", "brown"] descendingBySecondLastLetter = items.sort { a,b -> b[-2] <=> a[-2] } assert descendingBySecondLastLetter == ["brown", "fox", "the", "quick"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // warning: not an exact equivalent, idiomatic use would return copies def shift2 = {one = friends[0]; two = friends[1]; 2.times{friends.remove(0)}} friends = 'Peter Paul Mary Jim Tim'.split(' ').toList() shift2() assert one == 'Peter' assert two == 'Paul' assert friends == ["Mary", "Jim", "Tim"] def pop2(items) { items[0..1] } beverages = 'Dew Jolt Cola Sprite Fresca'.split(' ').toList() pair = pop2(beverages) assert pair == ["Dew", "Jolt"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- class Employee { def name def position def salary } staff = [new Employee(name:'Jim',position:'Manager',salary:26000), new Employee(name:'Jill',position:'Engineer',salary:24000), new Employee(name:'Jack',position:'Engineer',salary:22000)] highestEngineer = staff.find { emp -> emp.position == 'Engineer' } assert highestEngineer.salary == 24000 //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- engineers = staff.findAll { e -> e.position == 'Engineer' } assert engineers.size() == 2 highPaid = staff.findAll { e -> e.salary > 23000 } assert highPaid*.name == ["Jim", "Jill"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // sort works for numbers assert [100, 3, 20].sort() == [3, 20, 100] // strings representing numbers will be sorted alphabetically assert ['100', '3', '20'].sort() == ["100", "20", "3"] // closure style sorting allows arbitrary expressions for the comparison assert ['100', '3', '20'].sort{ a,b -> a.toLong() <=> b.toLong()} == ["3", "20", "100"] // obtain the following on unix systems using: 'ps ux'.execute().text processInput = ''' PID PPID PGID WINPID TTY UID STIME COMMAND 3868 1 3868 3868 con 1005 06:23:34 /usr/bin/bash 3456 3868 3456 3528 con 1005 06:23:39 /usr/bin/ps ''' nonEmptyLines = {it.trim()} lines = processInput.split("\n").findAll(nonEmptyLines)[1..-1] def col(n, s) { s.tokenize()[n] } commandIdx = 7 pidIdx = 0 ppidIdx = 1 linesByPid = lines.sort{ col(pidIdx,it).toLong() } assert col(commandIdx, linesByPid[0]) == '/usr/bin/ps' linesByPpid = lines.sort{ col(ppidIdx,it).toLong() } assert col(commandIdx, linesByPpid[0]) == '/usr/bin/bash' //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // sort staff from 4.12 by name assert staff.sort { a,b -> a.name <=> b.name }*.name == ["Jack", "Jill", "Jim"] // sort by first two characters of name and if equal by descending salary assert staff.sort { a,b -> astart = a.name[0..1] bstart = b.name[0..1] if (astart == bstart) return b.salary <=> a.salary return astart <=> bstart }*.name == ["Jack", "Jim", "Jill"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- items = [1, 2, 3, 4, 5] processed = [] 10.times{ processed << items[0] items = items[1..-1] + items[0] } assert processed == [1, 2, 3, 4, 5, 1, 2, 3, 4, 5] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- import java.text.DateFormatSymbols as Symbols items = new Symbols().shortWeekdays.toList()[1..7] assert items == ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] // not as random as you might expect println items.sort{ Math.random() } // => ["Sat", "Tue", "Sun", "Wed", "Mon", "Thu", "Fri"] // better to use the built-in method for this purpose Collections.shuffle(items) println items // => ["Wed", "Tue", "Fri", "Sun", "Sat", "Thu", "Mon"] //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- symbols = new Symbols() words = symbols.weekdays.toList()[1..7] + symbols.months.toList()[0..11] + symbols.eras.toList() + symbols.amPmStrings.toList() expected = // 'AD August February July May October September Tuesday \n' + 'AM BC Friday June Monday PM Sunday Wednesday \n' + 'April December January March November Saturday Thursday \n' class WordFormatter { def cols def process(list) { def sb = new StringBuffer() def colWidth = list.max{it.size()}.size() + 1 int columns = [cols/colWidth, 1].max() def numWords = list.size() int rows = (numWords + columns - 1) / columns for (row in 0..<rows) { for (col in 0..<columns) { def target = row + col * rows if (target < numWords) sb << list[target].padRight(colWidth) } sb << '\n' } return sb.toString() } } // get nr of chars that fit in window or console, see PLEAC 15.4 // hard-coded here but several packages are available, e.g. in JLine // use a concrete implementation of Terminal.getTerminalWidth() def getWinCharWidth() { 80 } // main script actual = new WordFormatter(cols:getWinCharWidth()).process(words.sort()) assert actual == expected //---------------------------------------------------------------------------------- |
//---------------------------------------------------------------------------------- // recursive version is simplest but can be inefficient def fact(n) { (n == 1) ? 1 : n * fact(n-1)} assert fact(10) == 3628800 // unwrapped version: note use of BigInteger def factorial(n) { def result = 1G // 1 as BigInteger while (n > 0) { result *= n n -= 1 } return result } expected = 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 assert expected == factorial(100) // println factorial(10000) // => 284625... (greater than 35,000 digits) // simple version but less efficient def simplePermute(items, perms) { if (items.size() == 0) println perms.join(' ') else for (i in items) { newitems = items.clone() newperms = perms.clone() newperms.add(i) newitems.remove(i) simplePermute(newitems, newperms) } } simplePermute(['dog', 'bites', 'man'], []) // => //dog bites man //dog man bites //bites dog man //bites man dog //man dog bites //man bites dog // optimised version below expected = ''' man bites dog man dog bites bites man dog bites dog man dog man bites dog bites man ''' // n2pat(n, len): produce the N-th pattern of length len def n2pat(n, length) { def pat = [] int i = 1 while (i <= length) { pat << (n % i) n = n.intdiv(i) i += 1 } pat } // pat2perm(pat): turn pattern returned by n2pat() into // permutation of integers. def pat2perm(pat) { def source = (0 ..< pat.size()).collect{ it/*.toString()*/ } def perm = [] while (pat.size() > 0) { def next = pat.remove(pat.size()-1) perm << source[next] source.remove(next) } perm } def n2perm(n, len) { pat2perm(n2pat((int)n,len)) } data = ['man', 'bites', 'dog'] sb = new StringBuffer() numPermutations = fact(data.size()) for (j in 0..<numPermutations) { def permutation = n2perm(j, data.size()).collect { k -> data[k] } sb << permutation.join(' ') + '\n' } assert '\n' + sb.toString() == expected //---------------------------------------------------------------------------------- |