2015-07-26 12 views
34

Chciałbym zrobić wydajniej następujący:Skutecznie powtórzyć znak/string n razy w Scala

def repeatChar(char:Char, n: Int) = List.fill(n)(char).mkString 
def repeatString(char:String, n: Int) = List.fill(n)(char).mkString 

repeatChar('a',3)  // res0: String = aaa 
repeatString("abc",3) // res0: String = abcabcabc 
+0

To może być nieco bardziej efektywny, jeśli użyjesz 'Stream'instead' 'List' –

Odpowiedz

67

Na strunach można po prostu napisać "abc" * 3, który działa poprzez StringOps i używa StringBuffer za kulisy.

Dla postaci Myślę, że twoje rozwiązanie jest całkiem rozsądne, chociaż char.toString * n jest prawdopodobnie czystszy. Czy masz jakiś powód, by podejrzewać, że wersja List.fill nie jest wystarczająco wydajna dla twoich potrzeb? Możesz napisać własną metodę, która użyłaby StringBuffer (podobnego do * na StringOps), ale sugerowałbym najpierw dążenie do jasności, a następnie martwienie się o wydajność tylko wtedy, gdy masz konkretne dowody na to, że jest to problem w twoim programie.

+3

Dziękuję Travis. To było bardziej z zainteresowań akademickich i, jak sugerowaliście, w celu poprawy przejrzystości, jeśli to możliwe, a nie potrzeby poprawy wydajności. Chciałem tylko upewnić się, że od początku zdobywam najlepsze praktyki. – TimY

+0

@TimY To ma sens - chciałabym, żeby więcej osób używało "efektywności" w kontekście innym niż wydajność! –

+0

Nie jestem pewien, jak ustalono rozsądek: czy ta odpowiedź opiera się na jakimkolwiek benchmarku w porównaniu z innymi opcjami, takimi jak manipulowanie zwykłymi ciągami Java lub cokolwiek innego, czy raczej chciałeś powiedzieć, że jest to idiomatyczny sposób w scala? – matanster

0

wiem, jest to stara sprawa, innym rozwiązaniem byłoby co mam poniżej

def repeatChar(char:Char, n: Int) : String = { 
    var result = "" 
    for(_ <- 1 to n){ 
     result += "" + char 
    } 
    result 

} 

wyniku z REPL repeatChar ('a', 2) => RES1: String = aa