2016-02-18 2 views
2

Я хочу создать набор с первым символом из набора строк. Похоже, я должен иметь возможность легко сопоставлять, но я не могу понять правильный синтаксис или найти его на SO или в остальной части Интернета. Вот где я нахожусь:Как создать набор Char из набора String в Scala

val mySetOfStrings = scala.collection.immutable.Set[String]() 
def charSet: Set[Char] = mySetOfStrings.map[Char]((s: String) => s.head) 

//IDE tells me "Expression of type Char doesn't conform to expected type B" 

Спасибо.

ответ

4

Ошибка IDE не является правильным, но вручную подачи параметров типа в map собирается вызвать проблемы, потому что подпись map действительно:

final def map[B, That](f: (A) ⇒ B)(implicit bf: CanBuildFrom[List[A], B, That]): That 

Так фактическая ошибка компилятора:

<console>:12: error: wrong number of type parameters for method map: [B, That](f: String => B)(implicit bf: scala.collection.generic.CanBuildFrom[scala.collection.immutable.Set[String],B,That])That 
     strings.map[Char](_.head) 
       ^

Обратите внимание, что есть два типа параметров, а не один. Однако компилятор сделает вывод Char.

scala> val strings = Set("abc", "def", "ijk") 

scala> strings.map(_.head) 
res1: scala.collection.immutable.Set[Char] = Set(a, d, i) 

вручную снабжая параметры типа должны выглядеть следующим образом:

scala> strings.map[Char, Set[Char]](_.head) 
res6: Set[Char] = Set(a, d, i) 
+3

Обратите внимание, что вызов' head' является _not_ safe, если какая-либо из строк пуста. В этом случае вы должны использовать 'flatMap (_. HeadOption)', чтобы игнорировать их. –

+0

Принимается, потому что вы заставили меня понять, где я ошибся. Тем не менее, благодарность другим (слегка) более быстрым ответам. –

2
scala> Set("foo", "bar", "baz").map(s => s.head) 
res0: scala.collection.immutable.Set[Char] = Set(f, b) 

Вы обычно не предоставляете аргументы типа методу карты самостоятельно.

+0

'Scala> Set ("Foo",«бар "," ") .map (s => s.head) java.util.NoSuchElementException: next on empty iterator' –

2

Если вы хотите игнорировать пустые строки во входном, то вы можете использовать:

mySetOfStrings.flatMap(_.headOption) 
1

Другой подход к обходя пустых строк,

mySetOfStrings.flatMap(_.take(1)) 
Смежные вопросы