groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Steve Amerige <Steve.Amer...@sas.com>
Subject Re: String to Array of Substrings by delimiter
Date Fri, 26 Jun 2015 18:59:36 GMT
Hi Shil,

I like this... thanks!  I've made the following first improvements by 
using *tokenize *instead of *split *and using a single Groovy string to 
clean up the syntax a bit:

     String s = '/a/b/c/d'
     s.tokenize('/').inject([]) { acc, val -> acc + "${acc ? acc.last() 
: ''}/$val" }

*    Result: [/a, /a/b, /a/b/c, /a/b/c/d]*


Then, to get rid of the ternary logic, I thought about adding a 
*withDefault *expression so that I could safely use last():

     String s = '/a/b/c/d'
     s.tokenize('/').inject([]*.withDefault {''}*) { acc, val -> acc + 
"${*acc.last()*}/$val" }

But the above throws *NoSuchElementException *when trying to reference 
*acc.last()*.  It does make sense: getting a default implies that an 
entry in the list gets created, but we don't want to create an object 
into the list.  So, one could add a delegate to solve this without 
dirtying the semantics of *last*:

     String s = '/a/b/c/d'
     List.metaClass.safelast = { delegate?.empty ? '' : delegate.last() }
     s.tokenize('/').inject([]) { acc, val -> acc + 
"${acc.safelast()}/$val" }

Thanks again Shil and Bahman for your ideas!

Enjoy,
Steve Amerige
Principal Software Developer, Fraud and Compliance Solutions Development
SAS Institute, 100 SAS Campus Dr, Room U3050, Cary, NC 27513-8617



On 6/26/2015 12:09 PM, Shil Sinha wrote:
> Not the best looking, but it's a one liner that works:
>
> s.split('/').tail().inject([]) { acc, val -> acc + ((!acc.isEmpty() ? 
> acc.last() : '') + "/$val") }
>
>
> On Fri, Jun 26, 2015 at 11:34 AM, Steve Amerige <Steve.Amerige@sas.com 
> <mailto:Steve.Amerige@sas.com>> wrote:
>
>     Hi all,
>
>     Suppose you have:
>
>         String s = '/a/b/c/d'     // guaranteed to begin with a / and
>     have at least one substring sequence after the /; can have more
>     than 4 as shown in this example
>
>     and I want the result:
>
>         [ '/a', '/a/b', '/a/b/c', '/a/b/c/d' ]
>
>     where '/' can be any single character delimiter.  What would be
>     the easiest, grooviest way to get that result?
>


Mime
View raw message