Я - новичок Scala. Я решил записать решатель пасьянса паука как первое осуществление для изучения языка и функционального программирования в целом.
Я хотел бы генерировать случайным образом переставленную деку карт, содержащих 1, 2, или 4 иска. Вот то, что я придумал:
val numberOfSuits = 1
(List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits) * 4).take(4)
который должен возвратиться
List("clubs", "clubs", "clubs", "clubs")
List("clubs", "diamonds", "clubs", "diamonds")
List("clubs", "diamonds", "hearts", "spades")
в зависимости от значения numberOfSuits кроме нет никакого Списка, "умножают" операцию, которую я могу найти. Я пропускал его? Существует ли лучший способ генерировать полную деку перед перестановкой?
BTW, я планирую использование Перечисления для исков, но было легче ввести мой вопрос со строками. Я возьму Список, сгенерированный выше и использование для понимания, выполню итерации по искам и подобному Списку карты "разрядов" для генерации полной деки.
Вам следует посмотреть скаладок для объекта List
. В нем есть множество интересных методов для создания списков. Например, следующее делает именно то, что вы пытались:
List.flatten(List.make(4, List("clubs", "diamonds", "hearts", "spades").take(numberOfSuits))).take(4)
Гораздо более приятный код, однако, был бы таким (Scala 2.7):
val suits = List("clubs", "diamonds", "hearts", "spades")
List.tabulate(4, i => suits.apply(i % numberOfSuits))
На Scala 2.8 tabulate
является curried, так что правильный синтаксис был бы:
List.tabulate(4)(i => suits.apply(i % numberOfSuits))
Сгладить конечные списки списков:
scala> List.fill(2)(List(1, 2, 3, 4)).flatten
res18: List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
Сгладить бесконечный Поток списков, взять первые 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)
Вы можете развернуть числовую последовательность и flatMap
вместо умножения.
scala> (1 to 3).flatMap(_=>List(1,2,3,4).take(2)).take(4)
res1: Seq[Int] = List(1, 2, 1, 2)
Это также работает в 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)
и теперь вы можете
scala> List(1,2,3)*4
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)
(Как правило, чтобы повторно использовать такие имплициты, объявите их в объекте, а затем импортируйте MyObject._, чтобы получить неявное преобразование и соответствующий класс в области видимости.)