Повторение списка в Scala

Я - новичок 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, я планирую использование Перечисления для исков, но было легче ввести мой вопрос со строками. Я возьму Список, сгенерированный выше и использование для понимания, выполню итерации по искам и подобному Списку карты "разрядов" для генерации полной деки.

8
задан Ralph 4 October 2012 в 15:44
поделиться

3 ответа

Вам следует посмотреть скаладок для объекта 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))
7
ответ дан 5 December 2019 в 05:25
поделиться

Сгладить конечные списки списков:

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)
18
ответ дан 5 December 2019 в 05:25
поделиться

Вы можете развернуть числовую последовательность и 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._, чтобы получить неявное преобразование и соответствующий класс в области видимости.)

6
ответ дан 5 December 2019 в 05:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: