common

multiple assignment

[!TIP] references:

'''1;Joe Doe;joedoe@example.com
2;Mark Doe
3;Clark Doe;clarkdoe@example.com;2
'''.eachLine{ line ->
  def (id, name, email, sibling) = line.tokenize(';')
  println """
         id : ${id}
       name : ${name}
      email : ${email}
    sibling : ${sibling}
  """
}
  • result

             id : 1
           name : Joe Doe
          email : joedoe@example.com
        sibling : null
    
             id : 2
           name : Mark Doe
          email : null
        sibling : null
    
             id : 3
           name : Clark Doe
          email : clarkdoe@example.com
        sibling : 2
    

Boolean

usage scenarios:

Boolean doMap( Map m ) { return true|false }
if ( map ) {
  doMap( map )
} else {
  return true
}

==> map ? doMap(map) : true

==> ! map || doMap(map)

try online

assert ( true ? foo() : true ) == ( ! true || foo() )

substring for integers

String str = 'abc12'
assert 'abc' == "${str - ~/\d+\s*/}"

get the first item if exists or null if empty

assert [:]?.find{true} == null
assert []?.find{true} == null
assert ['a']?.find{true} == 'a'
['a': '1'].find{ true }.each { println it.key + ' ~> ' + it.value }
println (['a': '1'].find{ true }.getClass())

// result
// a ~> 1
// class java.util.LinkedHashMap$Entry

split and trim in string

indices & indexed()

def rows = ['foo', 'bar']
println rows.indices
println rows.indexed()

===> result
0..<2
[0:foo, 1:bar]
  • usage

    def userList = [
      [name: 'user1', id:0, ip: '127.0.0.1'],
      [name: 'user2', id:1, ip: '127.0.0.2'],
      [name: 'user3', id:2, ip: '127.0.0.3']
    ]
    def rows = ['foo', 'bar']
    
    println rows.indices.collect { index ->                   // Using indices
      userList.find { it.id == index }
    }
    println rows.indexed().collect { index, item ->           // Using indexed()
      userList.find { it.id == index }
    }
    
    ===> result
    [[name:user1, id:0, ip:127.0.0.1], [name:user2, id:1, ip:127.0.0.2]]
    [[name:user1, id:0, ip:127.0.0.1], [name:user2, id:1, ip:127.0.0.2]]
    

elegant way to merge Map<String, List<String>> structure by using groovy

original Map structure wanted result

Map<String, List<String>> case_pool = [
  dev : [
    funcA : ['devA'] ,
    funcB : ['devB'] ,
    funcC : ['devC']
  ],
  'dev/funcA' : [
    funcA : ['performanceA']
  ],
  'dev/funcA/feature' : [
    funcA : ['performanceA', 'feature']
  ],
  staging : [
   funcB : ['stgB'] ,
   funcC : ['stgC']
  ]
]

String branch = 'dev/funcA/feature-1.0'

result:
[
  funcA: [ "devA", "performanceA", "feature" ],
  funcB: [ "devB" ],
  funcC: [ "devC" ]
]
  • original map structure:

    Map<String, List<String>> case_pool = [
      dev : [
        funcA : ['devA'] ,
        funcB : ['devB'] ,
        funcC : ['devC']
      ],
      'dev/funcA' : [
        funcA : ['performanceA']
      ],
      'dev/funcA/feature' : [
        funcA : ['performanceA', 'feature']
      ],
      staging : [
       funcB : ['stgB'] ,
       funcC : ['stgC']
      ]
    ]
    
  • method 1st: by using loop

    String branch = 'dev/funcA/feature-1.0'
    def result = [:].withDefault { [] as Set }
    case_pool.keySet().each {
      if ( branch.contains(it) ) {
        case_pool.get(it).each { k, v ->
          result[k].addAll(v)
        }
      }
    }
    println 'result: ' + result
    
  • method 2nd: by using closure

    String branch = 'dev/funcA/feature-1.0'
    def result = [:].withDefault { [] as Set }
    case_pool.findAll{ k, v -> branch.contains(k) }
             .collectMany{ k, v ->
                v.collect{ c, l ->
                  result[c].addAll(l)
                }
              }
    println 'result: ' + result
    
  • method 3rd: by using closure elegantly

    def result = case_pool.inject([:].withDefault { [] as Set }) { result, key, value ->
      if (branch.contains(key)) {
        value.each { k, v -> result[k] += v }
      }; result
    }
    println 'result: ' + result
    

fuzzy search and merge Map<String, Map<String, Map<String, String>>>

/**
 * "fuzzy" search and merge the {@code Map<String, Map<String, String>>} according to keywords.
 * To replace the hardcode 'keyword' search {@code case_pool.get(stg).get(keyword).values()}. example:
 * <pre><code>
 * keyword = 'dev/funcA/feature1'
 * fuzzyFindAll( case_pool, keyword )
 *  => Result: [funcA:[devA, performanceA, feature], funcB:[devB], funcC:[devC]]
 * </pre></code>
 *
 * @param map       the map structure for {@code Map<String, Map<String, String>>}
 * @param keyword   use branch as keyword normally
**/
def fuzzyFindAll( Map map, String keyword ) {
  Map result = [:]
  map.findAll{ k, v -> keyword.toLowerCase().contains(k.toLowerCase()) }.collect { k, v ->
    v.each { key, value ->
      result[key] = [ result.getOrDefault(key,[]) + value ].flatten().unique()
    }
  }
  return result
}

groupBy

groupBy List<List<String>> to Map<String, List>

requirements:

[ ["GX 470","Model"], ["Lexus","Make"], ["Jeep","Make"], ["Red","Color"], ["blue","Color"] ]

⇣⇣

["Model":["GX 470"],"Make":["Lexus","Jeep"],"Color":["Red", "blue"]]

  • solution

    def list = [
        ["GX-470","Model"],
        ["Lexus","Make"],
        ["Jeep","Make"],
        ["Red","Color"],
        ["blue","Color"]
    ]
    
    list.groupBy{ it[1] }.collectEntries{ k, v -> [(k): v.collect{it.get(0)}] }
    

alternatives

  list.inject([:].withDefault{[]}) { map, elem ->
    map[elem[1]] << elem[0]
    map
  }

groupBy List<Map<String,List<String>>>

[!NOTE|label:references:]

List<Map<String,List<String>>> lstData = [
  [ "Year":["FY19"] , "Period":["Oct"] , "Account":["A1000" , "A1001"]           ] ,
  [ "Year":["FY19"] , "Period":["Oct"] , "Account":["A1001" , "A1002"]           ] ,
  [ "Year":["FY19"] , "Period":["Nov"] , "Account":["A1000" , "A1001" , "A1002"] ] ,
  [ "Year":["FY19"] , "Period":["Dec"] , "Account":["A1000" , "A1002"]           ] ,
  [ "Year":["FY20"] , "Period":["Jan"] , "Account":["A1000" , "A1003"]           ]
]

lstData.groupBy { it.Year + it.Period }.collect { k, v ->
  v.tail().inject(v.head()) { r, c -> r.Account = (r.Account + c.Account).unique(); r }
}.groupBy { it.Account }.collect { k, v ->
  v.tail().inject(v.head()) { r, c ->
    r.Year = (r.Year + c.Year).unique()
    r.Period = (r.Period + c.Period).unique()
    r
  }
}
  • result
    [
        [
            "Year": [ "FY19" ],
            "Period": [ "Oct", "Nov" ],
            "Account": [ "A1000", "A1001", "A1002" ]
        ],
        [
            "Year": [ "FY19" ],
            "Period": [ "Dec" ],
            "Account": [ "A1000", "A1002" ]
        ],
        [
            "Year": [ "FY20" ],
            "Period": [ "Jan" ],
            "Account": [ "A1000", "A1003" ]
        ]
    ]
    

groupBy Map<String, Map<String, Object>>

[!NOTE|label:references:]

Map<String, Map<String, Object>> lineEdits = [
  flag:[
    [ id:10001 , mnemonic:'TRA' , action:'review' ] ,
    [ id:10002 , mnemonic:'REB' , action:'deny'   ] ,
    [ id:10003 , mnemonic:'UNB' , action:'deny'   ] ,
    [ id:20001 , mnemonic:'REB' , action:'deny'   ] ,
    [ id:20002 , mnemonic:'ICD' , action:'review' ] ,
    [ id:30001 , mnemonic:'REB' , action:'deny'   ] ,
    [ id:40001 , mnemonic:'ICD' , action:'review' ] ,
    [ id:40002 , mnemonic:'MPR' , action:'review' ] ,
    [ id:50001 , mnemonic:'CPT' , action:'deny'   ] ,
    [ id:60001 , mnemonic:'DTU' , action:'deny'   ] ,
    [ id:70001 , mnemonic:'ICD' , action:'review' ] ,
    [ id:70002 , mnemonic:'MPR' , action:'review' ]
  ]
]

def editsMap = lineEdits.flag
                        .groupBy { it.id } // Group by id
                        .collectEntries { k, v ->
                          [ k, v[ 0 ] ] // Just grab the first one (flatten)
                        }
  • result
    [
        "10001": [ "id": 10001, "mnemonic": "TRA", "action": "review" ] ,
        "10002": [ "id": 10002, "mnemonic": "REB", "action": "deny"   ] ,
        "10003": [ "id": 10003, "mnemonic": "UNB", "action": "deny"   ] ,
        "20001": [ "id": 20001, "mnemonic": "REB", "action": "deny"   ] ,
        "20002": [ "id": 20002, "mnemonic": "ICD", "action": "review" ] ,
        "30001": [ "id": 30001, "mnemonic": "REB", "action": "deny"   ] ,
        "40001": [ "id": 40001, "mnemonic": "ICD", "action": "review" ] ,
        "40002": [ "id": 40002, "mnemonic": "MPR", "action": "review" ] ,
        "50001": [ "id": 50001, "mnemonic": "CPT", "action": "deny"   ] ,
        "60001": [ "id": 60001, "mnemonic": "DTU", "action": "deny"   ] ,
        "70001": [ "id": 70001, "mnemonic": "ICD", "action": "review" ] ,
        "70002": [ "id": 70002, "mnemonic": "MPR", "action": "review" ]
    ]
    

get object id (python -c 'id('abc'))

java.lang.System.identityHashCode( obj )
  • example

    String s = 'abc'
    String x = s
    println java.lang.System.identityHashCode(s)
    println java.lang.System.identityHashCode(x)
    x = s + 'aa'
    println java.lang.System.identityHashCode(x)
    
    ==>
    51571311
    51571311
    733591550
    
  • example for identityHashCode() and hashCode()

    String a = new String("hhh")
    String b = new String("hhh")
    
    assert System.identityHashCode(a) != System.identityHashCode(b)
    assert a.hashCode() == b.hashCode()
    

loop if not empty

[]?.each{ println it } ?: println( 'empty' )
[:]?.each{ k, v -> println "${k} :: ${v}" } ?: println( 'empty' )
  • details
    assert [:]?.each{ k, v -> println "${k} :: ${v}" } == true
                |                                      |
                [:]                                    false
    

getField()

groovy:000 > 'aaa'.getClass().getFields()
===> [public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER]

generate the random String

[!NOTE] check also in * imarslo : random

String alphabet = (('a'..'z') + ('A'..'Z') + ('0'..'9')).join()
println new Random().with { (1..8).collect { alphabet[ nextInt( alphabet.length() ) ] }.join() }
  • or
    Closure generator = { String alphabet, int n ->
      new Random().with {
        (1..n).collect { alphabet[ nextInt( alphabet.length() ) ] }.join()
      }
    }
    String charset = (('A'..'Z')+('0'..'9')+('a'..'z')).join()
    randomValue = generator( charset, 15 )
    

dynamic method names

def codecs = classes.findAll { it.name.endsWith('Codec') }

codecs.each { codec ->
    Object.metaClass."encodeAs${codec.name-'Codec'}" = { codec.newInstance().encode(delegate) }
    Object.metaClass."decodeFrom${codec.name-'Codec'}" = { codec.newInstance().decode(delegate) }
}

def html = '<html><body>hello</body></html>'
assert '<html><body>hello</body></html>' == html.encodeAsHTML()

instanceof

[!NOTE]

assert '' instanceof String

Class clz = ''.getClass()

assert '' in clz
assert 0 in clz == false

assert clz.isCase( '' )
assert clz.isCase( [] ) == false

assert clz.isAssignableFrom( ''.getClass() )
assert clz.isAssignableFrom( [:].getClass() ) == false

assert clz.isInstance( '' )
assert clz.isInstance( [] ) == false

run groovy from docker

$ docker run \
         --rm \
         -e hola=caracola \
         -it \
         groovy:latest groovy -e "System.getenv().each{ println it }"
  • mount volume
    $ docker run \
             --rm \
             -v "$PWD":/home/marslo/scripts \
             -w /home/marslo/scripts \
             groovy:latest \
             groovy DockerBasico.groovy -a
    
    • DockerBasico.groovy
      if ( options.a ) {
        println "------------------------------------------------------------------"
        System.getenv().each{ println it }
        println "------------------------------------------------------------------"
      }
      
  • with Json

    $ docker run \
      --rm \
      -v "$PWD":/home/marslo/scripts \
      -w /home/marslo/scripts \
      groovy:latest groovy DockerBasico.groovy -d
    
    • DockerBasico.groovy

      > how to download the image via json
      

      if( options.d ){
        def json = new groovy.json.JsonSlurper().parse( new URL("https://dog.ceo/api/breed/hound/images/random")  )
        if( json.status=='success' ){
          new File('perrito.jpg').bytes =  new URL(json.message).bytes
        }
      }
      

MetaClass

[!NOTE] references:

class Stuff {
   def invokeMe() { "foo" }
}

Stuff.metaClass.invokeMethod = { String name, args ->
   def metaMethod = Stuff.metaClass.getMetaMethod(name, args)
   def result
   if(metaMethod) result = metaMethod.invoke(delegate,args)
   else {
      result = "bar"
   }
   result
}

def stf = new Stuff()

assert "foo" == stf.invokeMe()
assert "bar" == stf.doStuff()

get supported methods

String s = 'aa'
println s.metaClass.methods.name
  • result

    [equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait, charAt, codePointAt, codePointBefore, codePointCount, compareTo, compareToIgnoreCase, concat, contains, contentEquals, contentEquals, copyValueOf, copyValueOf, endsWith, equals, equalsIgnoreCase, format, format, getBytes, getBytes, getBytes, getBytes, getChars, hashCode, indexOf, indexOf, indexOf, indexOf, intern, isEmpty, join, join, lastIndexOf, lastIndexOf, lastIndexOf, lastIndexOf, length, matches, offsetByCodePoints, regionMatches, regionMatches, replace, replace, replaceAll, replaceFirst, split, split, startsWith, startsWith, subSequence, substring, substring, toCharArray, toLowerCase, toLowerCase, toString, toUpperCase, toUpperCase, trim, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf, valueOf]
    
  • or print by sort

    println <var>.metaClass.methods*.name.sort().unique()
    

A Bit of metaClass DSL

String.metaClass {
    or << { String s -> delegate.plus(' or ').plus(s) }
    or << { List l -> delegate.findAll("(${l.join('|')})") }
    and { String s -> delegate.plus(' and ').plus(s) }
    'static' {
        groovy { 'Yeah man!' }
    }
}

assert 'Groovy or Java?' == ("Groovy" | "Java?")
assert ['o', 'o', 'y'] == ("Groovy" | ['o', 'y'])
assert 'Groovy and Java!' == ("Groovy" & "Java!")
assert 'Yeah man!' == String.groovy()
  • metaClass with Closure

    List.metaClass.eachUntilGreaterThanFive = { closure ->
      for ( value in delegate ) {
        if ( value  > 5 ) break
        closure(value)
      }
    }
    
    [1, 2, 3, 4, 5, 6, 7].eachUntilGreaterThanFive {
      println it
    }
    

get class name

Sting s = 'string'
println s.metaClass.getTheClass()   // Class
println s.getClass()                // Class
println s.class.name                // String
  • output
    class java.lang.String
    class java.lang.String
    java.lang.String
    

dynamically call methods

references:

def doPrint( String platform, String string ) {
 this."do${platform.toLowerCase().capitalize()}Print"( string )
}

def doLinuxPrint( String string ) {
  println "from Linux: ${string}"
}

def doWindowsPrint( String string ) {
  println "from Windows: ${string}"
}

def doDockerPrint( String string ) {
  println "from Docker: ${string}"
}

doPrint( 'LINUX', 'awesome marslo!' )
doPrint( 'dOCKER', 'awesome marslo!' )
  • result
    from Linux: awesome marslo!
    from Docker: awesome marslo!
    

others

groovy cli (args) with options

reference:

def cli = new CliBuilder(usage: 'groovy DockerBasico.groovy]')

cli.with {
  h(longOpt: 'help',    'Usage Information \n', required: false)
  a(longOpt: 'Hello','Al seleccionar "a" te saludara ', required: false)
  d(longOpt: 'Dogs', 'Genera imagenes de perros', required:false)
}

def options = cli.parse(args)

if ( !options || options.h ) {
  cli.usage
  return
}

//tag::hello[]
if ( options.a ) {
  println "------------------------------------------------------------------"
  println "Hello"
  System.getenv().each{ println it }
  println "------------------------------------------------------------------"
}
//end::hello[]

//tag::dogs[]
if ( options.d ){
  def json = new groovy.json.JsonSlurper().parse( new URL("https://dog.ceo/api/breed/hound/images/random")  )
  if( json.status=='success' ){
    new File('perrito.jpg').bytes =  new URL(json.message).bytes
  }
}
//end::dogs[]

Get variable value for its name

import groovy.text.SimpleTemplateEngine

def binding = [ VAL1:'foo', VAL2:'bar' ]
def template = 'hello ${VAL1}, please have a ${VAL2}'     // single quotes

println new SimpleTemplateEngine().createTemplate( template ).make( binding ).toString()

groovy.lang.Binding

  • this.binding

    reference:

    baz = [ 'a':'b' ]
    foo = "abc"
    bar = "def"
    
    println this.binding.hasVariable('baz')
    this.binding.variables.each{ println "${it.key} : ${it.value}" }
    
    • result
      true
      args : []
      baz : [a:b]
      foo : abc
      bar : def
      
  • new Binding()

    String beans = 'aabbcc-beans-ddeeff'
    Binding b = new Binding();
    b.setVariable("beans", beans);
    b.variables.each{ println "${it.key} : ${it.value}" }
    
  • binding.setVariable()

    m = [ 'a' : '1', 'b' : '2' ]
    binding.setVariable("a", m)
    this.binding.variables.each{ println "${it.key} : ${it.value}" }
    
    • result
      args : []
      m : [a:1, b:2]
      a : [a:1, b:2]
      

load groovy file

sample.groovy:

#!/usr/bin/env groovy
import groovy.transform.Field

@Field final Map<String, Map<String, String>> SAMPLE = [
  k1 : [ 'k11' : 'v11' ] ,
  k2 : [ 'k21' : 'v21', 'k22' : 'v22' ]
]

references:

GroovyShell()

  • new GroovyShell().parse(new File('/path/to/file'))

    Object sample = new GroovyShell().parse(new File('/path/to/sample.groovy'))
    println """
      sample.getClass() : ${sample.getClass()}
       sample.SAMPLE.k1 : ${sample.SAMPLE.k1}
    """
    
    • result
        sample.getClass() : class sample
         sample.SAMPLE.k1 : [k11:v11]
      
  • Object.with{}

    Object sample = new GroovyShell().parse(new File('/path/to/sample.groovy'))
    sample.with{
      println SAMPLE
      println SAMPLE.k1
    }
    
    • result
      [k1:[k11:v11], k2:[k21:v21, k22:v22]]
      [k11:v11]
      

GroovyClassLoader()

  • new GroovyClassLoader().parseClass("/path/to/sample.groovy" as File)

    Class clazz = new GroovyClassLoader().parseClass("/path/to/sample.groovy" as File)
    println """
                 clazz.getClass() : ${clazz.getClass()}
       clazz.newInstance().SAMPLE : ${clazz.newInstance().SAMPLE}
    """
    
    • result
                 clazz.getClass() : class java.lang.Class
       clazz.newInstance().SAMPLE : [k1:[k11:v11], k2:[k21:v21, k22:v22]]
      
  • this.class.classLoader.parseClass(new File("/path/to/sample.groovy"))

    Class myClazz = this.class.classLoader.parseClass(new File("/Users/marslo/Desktop/sample.groovy"))
    println """
               myClazz.getClass() : ${myClazz.getClass()}
     myClazz.newInstance().SAMPLE : ${myClazz.newInstance().SAMPLE}
    """
    
    • result
                 myClazz.getClass() : class java.lang.Class
       myClazz.newInstance().SAMPLE : [k1:[k11:v11], k2:[k21:v21, k22:v22]]
      
  • new GroovyClassLoader(getClass().getClassLoader()).parseClass(new File("/path/to/sample.groovy"))

    Class gClass = new GroovyClassLoader(getClass().getClassLoader()).parseClass(new File("/path/to/sample.groovy"));
    println """
                gClass.getClass() : ${gClass.getClass()}
      gClass.newInstance().SAMPLE : ${gClass.newInstance().SAMPLE}
    """
    
    • result
                gClass.getClass() : class java.lang.Class
      gClass.newInstance().SAMPLE : [k1:[k11:v11], k2:[k21:v21, k22:v22]]
      

metaClass

Object sample = new GroovyShell().parse(new File('/path/to/sample.groovy'))
println sample.metaClass.hasProperty(sample, 'SAMPLE').type
println sample.metaClass.hasProperty(sample, 'SAMPLE').name
  • result
    interface java.util.Map
    SAMPLE
    

or

Class clazz = new GroovyClassLoader().parseClass("/path/to/sample.groovy" as File)
println clazz.metaClass.hasProperty(clazz, 'SAMPLE').dump()
  • result
    <org.codehaus.groovy.reflection.CachedField@6b915a64 field=final java.util.Map sample.SAMPLE madeAccessible=true name=SAMPLE type=interface java.util.Map>
    

more

def importScript(def scriptFile) {
  def script = new GroovyShell().parse(new File(scriptFile))
    script.metaClass.methods.each {
      if (it.declaringClass.getTheClass() == script.class && ! it.name.contains('$') && it.name != 'main' && it.name != 'run') {
      this.metaClass."$it.name" = script.&"$it.name"
    }
  }
}

importScript('File1.groovy')
method()
Copyright © marslo 2020-2023 all right reserved,powered by GitbookLast Modified: 2024-05-16 01:41:37

results matching ""

    No results matching ""