Ruby Oneliner与Groovy比较

3
我正在阅读《Ruby on Rails 教程》并看到以下一行代码: railstutorial
('a'..'z').to_a.shuffle[0..7].join

它创建随机的7个字符域名,如下所示:

 hwpcbmze.heroku.com
 seyjhflo.heroku.com
 jhyicevg.heroku.com

我尝试将这个一行代码转换为Groovy,但是我只能想出以下代码:

def range = ('a'..'z')
def tempList = new ArrayList (range)
Collections.shuffle(tempList)
println tempList[0..7].join()+".heroku.com"

上述代码能否改进并缩短为一行?我试图通过以下方式缩短代码:

println Collections.shuffle(new ArrayList ( ('a'..'z') ))[0..7].join()+".heroku.com"

然而,显然Collections.shuffle(new ArrayList ( ('a'..'z') ))返回了一个null
4个回答

3

没有内置的shuffle功能会增加代码长度,但这里有一个一行代码的解决方案:

('a'..'z').toList().sort{new Random().nextInt()}[1..7].join()+".heroku.com"

你的代码不起作用是因为Collections.shuffle执行的是原地洗牌,没有返回任何内容。如果要将其用作一行代码,需要这样做:

('a'..'z').toList().with{Collections.shuffle(it); it[1..7].join()+".heroku.com"}

2
不错...稍微简短一点:('a'..'z').toList().sort{Math.random()}[1..7].join()+".heroku.com" - mbrevoort
请注意,在 Java 7 中,这有时会失败,因为它们已经默认使用 Timsort,并且期望两个值之间的比较保持不变。 - tim_yates

2

这不是一行代码,但另一种使用Groovy的方法是向字符串添加一个shuffle方法...

String.metaClass.shuffle = { range ->
def r = new Random()
delegate.toList().sort { r.nextInt() }.join()[range]}

然后你会得到一些非常类似于Ruby的东西...

('a'..'z').join().shuffle(0..7)+'.heroku.com'

1
我最喜欢这个; 我认为这是更棒的解决方案 =D 虽然我认为在扩展方法中使用 Collections.shuffle 来完成工作会更清晰一些。 - epidemian

0

这绝对不如 Ruby 的同类那么精美,但正如 Ted 提到 的,这主要是因为在 Collections 中,shuffle 方法是静态方法。

[*'a'..'z'].with{ Collections.shuffle it; it }.take(7).join() + '.heroku.com'

我正在使用展开运算符技巧将范围转换为列表 :)

0

这是我的尝试。它是一行代码,但允许字符重复。虽然它不执行洗牌,但生成适合随机域名的输出。

我将其发布为递归匿名闭包的示例:

{ i -> i > 0 ? "${(97 + new Random().nextInt(26) as char)}" + call(i-1) : "" }.call(7) + ".heroku.com"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接