Jak stworzyć listę z tym samym elementem n-krotnie?

92

Jak stworzyć listę z tym samym elementem n-krotnie?

Wdrożenie ręczne:

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)

Czy istnieje również wbudowany sposób, aby zrobić to samo?

John Threepwood
źródło

Odpowiedzi:

11

Używając w tabulateten sposób,

List.tabulate(3)(_ => "foo")
wiąz
źródło
9
(1 to n).map( _ => "foo" )

Działa jak marzenie.

Danilo M. Oliveira
źródło
@AlonsodelArte Dlaczego jest to marnotrawstwo?
k0pernikus
@ k0pernikus Ponieważ wartość _nie ma znaczenia. Można to zrobić n to 1 by -1, -1 to -n by -1itp.
Alonso del Arte
1
@AlonsodelArte Na koniec potrzebna jest tymczasowa zmienna pętli. Nawet fillimplementacja metody konstruuje wewnętrznie zmienną tymczasową, której wartość nie miałaby znaczenia, o ile daje odpowiednią wartość na liście. Więc nie mam nic przeciwko nieużywanemu _.
k0pernikus
1
@ k0pernikus Nie miałbym nic przeciwko temu ani w lokalnej Scali REPL, ani we fragmencie Scastie. Ale w przypadku profesjonalnego projektu uznałbym to za wystarczający powód do refaktoryzacji.
Alonso del Arte
1

Mam inną odpowiedź, która chyba emuluje flatMap (okazało się, że to rozwiązanie zwraca Unit podczas stosowania 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)(_) }

ale to jest raczej dla z góry określonej listy i chcesz powielić n razy każdy element

Tomás Duhourq
źródło