尝试从字符列表中生成映射到其频率的唯一字符列表 - 例如类似的东西:
List('a','b','a') -> List(('a',2), ('b',1))
所以,只是在控制台中乱窜,这有效:
val l = List('a', 'b', 'c', 'b', 'c', 'a')
val s = l.toSet
s.map(i => (i, l.filter(x => x == i).size))
但是,仅仅通过组合最后两行来缩短?
l.toSet.map(i => (i, l.filter(x => x == i).size))
给出错误“缺少参数类型”。
有人可以解释为什么Scala会抱怨这种语法吗?
答案 0 :(得分:22)
当你说val s = l.toSet
时,编译器认为toSet
唯一明智的类型是Char
- 这是最具体的选择。然后,假设s
是一组Char
,编译器会意识到地图必须来自Char
。
但在第二种情况下,它拒绝判断toSet
中的元素类型是什么。它可能是Char
,但AnyVal
也可以,Any
也可以。
l.toSet.map((i: Any) => (i, l.filter(x => x == i).size))
通常规则是编译器应该选择最具体的值。但由于函数在其参数中是逆变的,因此当它们以Any
作为参数时它们是最具体的,因此编译器无法决定。可能存在打破平局的规则(“更喜欢早期假设”),但没有实施。所以它要求你的帮助。
您可以在函数参数或toSet
上提供类型来解决问题:
l.toSet.map((i: Char) => (i, l.filter(x => x == i).size))
l.toSet[Char].map(i => (i, l.filter(x => x == i).size))
答案 1 :(得分:3)
将[Char]类型添加到toSet
就可以了。
scala> l.toSet[Char].map(i => (i, l.filter(x => x == i).size))
scala.collection.immutable.Set[(Char, Int)] = Set((a,2), (b,2), (c,2))