在Scala中重复列表

Ral*_*lph 8 scala

我是Scala noob.我决定写一个蜘蛛纸牌解算器作为第一个练习,以学习语言和函数式编程.

我想生成一个包含1,2或4套西装的随机洗牌.这是我想出的:

val numberOfSuits = 1
(List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits) * 4).take(4)
Run Code Online (Sandbox Code Playgroud)

应该返回

List("clubs", "clubs", "clubs", "clubs")
List("clubs", "diamonds", "clubs", "diamonds")
List("clubs", "diamonds", "hearts", "spades")
Run Code Online (Sandbox Code Playgroud)

取决于numberOfSuits的值,除了没有我可以找到的List"multiply"操作.我错过了吗?在洗牌之前是否有更好的方法来生成完整的牌组?

顺便说一句,我打算在套装中使用Enumeration,但用字符串输入我的问题更容易.我将采用上面生成的列表并使用for comprehension,迭代套装和类似的卡片"排名"列表以生成完整的套牌.

ret*_*nym 18

展平有限的列表列表:

scala> List.fill(2)(List(1, 2, 3, 4)).flatten
res18: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

展平无限的列表流,取前N个元素:

scala> Stream.continually(List(1, 2, 3, 4)).flatten.take(8).toList
res19: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)


Dan*_*ral 7

你应该查找对象的scaladoc List.它有各种有趣的方法来创建列表.例如,以下内容完全符合您的要求:

List.flatten(List.make(4, List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits))).take(4)
Run Code Online (Sandbox Code Playgroud)

然而,更好的代码就是这个(Scala 2.7):

val suits = List("clubs", "diamonds", "hearts", "spades")
List.tabulate(4, i => suits.apply(i % numberOfSuits))
Run Code Online (Sandbox Code Playgroud)

在Scala 2.8上tabulate是curry,所以正确的语法是:

List.tabulate(4)(i => suits.apply(i % numberOfSuits))
Run Code Online (Sandbox Code Playgroud)

  • 这里的代码`List.tabulate(4,i => suits.apply(i%numberOfSuits))`不需要`apply`调用.我会把它改成`List.tabulate(4,i => suit(i%numberOfSuits))` (2认同)

Rex*_*err 6

您可以展开数字序列而flatMap不是乘法.

scala> (1 to 3).flatMap(_=>List(1,2,3,4).take(2)).take(4)
res1: Seq[Int] = List(1, 2, 1, 2)
Run Code Online (Sandbox Code Playgroud)

这也适用于2.7.x.


编辑:由于您对Scala的经验不足,您可能还没有遇到过pimp-my-library模式.如果您想要大量增加列表,可以添加自定义转换类:

class MultipliableList[T](l: List[T]) {
  def *(n: Int) = (1 to n).flatMap(_=>l).toList
}
implicit def list2multipliable[T](l: List[T]) = new MultipliableList[T](l)
Run Code Online (Sandbox Code Playgroud)

现在你可以

scala> List(1,2,3)*4
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

(通常,要重用这些implicits,请在对象中声明它们,然后导入MyObject._以获取隐式转换和范围内的相应类.)