Ruby Oneliner vs Groovy
-
21-09-2019 - |
Pergunta
Eu estava passando Railstatorial e vi o seguinte um forro
('a'..'z').to_a.shuffle[0..7].join
Cria nome aleatório de domínio de 7 caracteres, como a seguinte:
hwpcbmze.heroku.com
seyjhflo.heroku.com
jhyicevg.heroku.com
Eu tentei converter o único forro para groovy, mas só conseguia inventar:
def range = ('a'..'z')
def tempList = new ArrayList (range)
Collections.shuffle(tempList)
println tempList[0..7].join()+".heroku.com"
O exposto acima pode ser melhorado e feito para um revestimento? Eu tentei tornar o código acima mais curto por
println Collections.shuffle(new ArrayList ( ('a'..'z') ))[0..7].join()+".heroku.com"
No entanto, aparentemente Collections.shuffle(new ArrayList ( ('a'..'z') ))
é um null
Solução
Não ter o Shuffle embutido adiciona mais ao comprimento, mas aqui está um revestimento que fará isso:
('a'..'z').toList().sort{new Random().nextInt()}[1..7].join()+".heroku.com"
O seu não funciona porque as coleções. A luta faz uma embarcação no lugar, mas não retorna nada. Para usar isso como um revestimento, você precisaria fazer isso:
('a'..'z').toList().with{Collections.shuffle(it); it[1..7].join()+".heroku.com"}
Outras dicas
Não é uma linha, mas outra maneira groovy de fazer isso é adicionar um método de shuffle para string ...
String.metaClass.shuffle = { range ->
def r = new Random()
delegate.toList().sort { r.nextInt() }.join()[range]}
E então você tem algo muito parecido com rubi ...
('a'..'z').join().shuffle(0..7)+'.heroku.com'
Esta é a minha tentativa. É uma linha, mas permite a repetição de personagens. Ele não executa um shuffle, embora gerem uma saída adequada para um nome de domínio aleatório.
Estou postando como exemplo de um fechamento anônimo recursivo:
{ i -> i > 0 ? "${(97 + new Random().nextInt(26) as char)}" + call(i-1) : "" }.call(7) + ".heroku.com"
Definitivamente, isso não é tão bonito quanto o colega rubi, mas, como Ted mencionado, é principalmente por causa do fato de que shuffle
Método é um método estático em Collections
.
[*'a'..'z'].with{ Collections.shuffle it; it }.take(7).join() + '.heroku.com'
Estou usando o truque do operador espalhado para converter o intervalo em uma lista :)