Как создать список с одним и тем же элементом n раз?

91

Как создать список с одним и тем же элементом n раз?

Реализация вручную:

scala> def times(n: Int, s: String) =
 | (for(i <- 1 to n) yield s).toList
times: (n: Int, s: String)List[String]

scala> times(3, "foo")
res4: List[String] = List(foo, foo, foo)

Есть ли встроенный способ сделать то же самое?

Джон Трипвуд
источник

Ответы:

167

См scala.collection.generic.SeqFactory.fill (п: Int) (эль: => A) , что структуры сбора данных, как Seq, Stream, Iteratorи так далее, удлиняют:

scala> List.fill(3)("foo")
res1: List[String] = List(foo, foo, foo)

ВНИМАНИЕ! Это недоступно в Scala 2.7.

Кирицуку
источник
См GenTraversableFactory для получения дополнительной информации, а также # 14 на этой странице: nicholassterling.wordpress.com/2012/01/28/scala-snippets
AmigoNico
11

Используя tabulateвот так,

List.tabulate(3)(_ => "foo")
вяз
источник
9
(1 to n).map( _ => "foo" )

Работает как шарм.

Данило М. Оливейра
источник
@AlonsodelArte Почему это расточительно?
k0pernikus 09
@ k0pernikus Потому что значение _не имеет значения. Вы могли бы сделать n to 1 by -1, -1 to -n by -1и т.д.
Алонсо дель Арте
1
@AlonsodelArte В конце концов, нужна временная переменная цикла. Даже реализация fillметода внутренне конструирует временную переменную, значение которой не имеет значения, пока она производит нужное количество в списке. Так что я не против неиспользованных _.
k0pernikus
1
@ k0pernikus Я бы не стал возражать ни в локальном Scala REPL, ни в сниппете Scastie. Но в профессиональном проекте я считаю это достаточным поводом для рефакторинга.
Алонсо дель Арте,
1

У меня есть еще один ответ, который, как мне кажется, эмулирует flatMap (выяснилось, что это решение возвращает Unit при применении duplicateN)

 implicit class ListGeneric[A](l: List[A]) {
  def nDuplicate(x: Int): List[A] = {
    def duplicateN(x: Int, tail: List[A]): List[A] = {
      l match {
       case Nil => Nil
       case n :: xs => concatN(x, n) ::: duplicateN(x, xs)
    }
    def concatN(times: Int, elem: A): List[A] = List.fill(times)(elem)
  }
  duplicateN(x, l)
}

}

def times(n: Int, ls: List[String]) = ls.flatMap{ List.fill(n)(_) }

но это скорее для предопределенного списка, и вы хотите продублировать n раз каждый элемент

Томас Духурк
источник