2012-11-28 3 views
8

Si j'ai l'expression "New York City", comment puis-je obtenir la première lettre de chaque mot? Mon googling m'a seulement montré comment capitaliser la première lettre de chaque mot, ce qui est apparemment différent de ce que j'essaie de faire. Compte tenu de ma connaissance limitée de Scala, je pourrais probablement faire cela de manière procédurale mais j'espérais que quelqu'un pourrait me parler de Scala et me montrer un exemple qui décrit une approche fonctionnelle de ce problème.Comment obtenir la première lettre de chaque mot dans scala?

Répondre

24

Toutes les autres versions fonctionnent bien, mais afin d'éviter l'échec avec des chaînes mal formatées (deux blancs dans une rangée, une chaîne vide), utilisez

"New York City".split(" ").flatMap(_.headOption).mkString 

qui fonctionne aussi pour

"New York City".split(" ").flatMap(_.headOption).mkString 

ou même

"".split(" ").flatMap(_.headOption).mkString 

Comme suggéré par dhg, on peut vouloir utiliser une expression rationnelle plus appropriée telle que "\\s+" ainsi. Mais on pourrait tout aussi bien utiliser quelque chose d'encore plus approprié:

"""\w+""".r.findAllIn("New York City").map(_.head).mkString 

(Ici le /\w+/ devrait, espérons-nous épargner des cas pathologiques afin que nous puissions aller avec la version .head.)

+3

' "New York City" .split ("\\ s +") carte. (_. Tête).mkString' accomplit le même but sans le 'Option'. – dhg

+2

@dhg ... mais échoue sur la chaîne vide. – Debilski

+0

vous pouvez filtrer les résultats vides, en n'en conservant que les valides, ce qui vous permettra d'utiliser la méthode '_.head':' "New York City" .split ("") .filterNot (_. IsEmpty) .map (_ .head) .mkString' –

13
scala> "New York City".split(" ").map(_.head).mkString 
res5: String = NYC 

Ceci se sépare par "" en un tableau de mots. Ensuite, nous mappons sur ce tableau et appelons String.head qui obtient le premier caractère.

5
"New York City".split(" ").toList.map(_(0)) 

donne les personnages:

List[Char] = List(N, Y, C) 

Si vous voulez une chaîne mkString utiliser sur le List[Char]:

"New York City".split(" ").toList.map(_(0)) mkString 

pour obtenir:

String = NYC 
4
"New York City".split(" ").map(_.charAt(0)) 

vous donnera un tableau de caractères

2

est ici une alternative à en utilisant split (Regex). L'astuce ici est d'utiliser zip pour permettre le test du caractère courant et précédent dans la même itération lorsque vous traversez la chaîne, les limites de mots sont constituées de n'importe quelle lettre précédée d'une non-lettre. Les deux cas spéciaux, la première et la dernière lettre, sont gérés par 1) en ajoutant un espace à une copie de la chaîne qui définit également le biais de 1 caractère requis pour le zip et 2) zip tronque les paires partielles.

val s = "\n1New\n\t \t \tYork --City\n\t" 


def firstLetters(s: String) = { 
    " "+s zip s collect {case (w, c) if ! w.isLetter && c.isLetter => c} 
} 

firstLetters(s) 

retours

Vector(N, Y, C) 
Questions connexes