注意:这是一个常见问题解答,具体问我所以我可以自己回答,因为这个问题似乎经常出现,我想把它放在一个可以(希望)通过搜索很容易找到的地方
根据我在这里的回答评论提示
例如:
"abcde" map {_.toUpperCase} //returns a String
"abcde" map {_.toInt} // returns an IndexedSeq[Int]
BitSet(1,2,3,4) map {2*} // returns a BitSet
BitSet(1,2,3,4) map {_.toString} // returns a Set[String]
Run Code Online (Sandbox Code Playgroud)
查看scaladoc,所有这些都使用了map继承自的操作TraversableLike,那么为什么它始终能够返回最具体的有效集合呢?甚至String,它map通过隐式转换提供.
我想将a转换Map[Int, Any]为a SortedMap或a TreeMap.有一个简单的方法吗?
我有一个Seq类的对象,如下所示:
class A (val key: Int, ...)
Run Code Online (Sandbox Code Playgroud)
现在我想将此转换Seq为a Map,使用key每个对象的值作为键,并将对象本身作为值.所以:
val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?
Run Code Online (Sandbox Code Playgroud)
如何在Scala 2.8中高效且优雅地完成这项工作?
我正在寻找一个转化的最佳途径collection.mutable.Seq[T]来collection.immutable.Seq[T].
我非常喜欢函数式编程概念,但是当我在一个集合中进行映射时Set(即自动删除重复项),我现在被同一个问题所困在两个不同的场合.问题是在转换这样一个集合的元素之后,输出容器也是一个集合,因此删除了转换输出的任何重复.
一个非常简短的REPL会议来说明这个问题:
scala> case class Person(name: String, age: Int)
defined class Person
scala> val students = Set(Person("Alice", 18), Person("Bob", 18), Person("Charles", 19))
students: scala.collection.immutable.Set[Person] = Set(Person(Alice,18), Person(Bob,18), Person(Charles,19))
scala> val totalAge = (students map (_.age)).sum
totalAge: Int = 37
Run Code Online (Sandbox Code Playgroud)
我当然希望总年龄为18 + 18 + 19 = 55,但因为学生 们存放在a中Set,所以他们的年龄也是如此,因此其中一个18在年龄之前消失了.
在实际代码中,这通常更加隐蔽,更难以发现,特别是如果您编写实用程序代码,它只需要Traversable和/或使用声明返回的方法的输出Traversable(其实现恰好是Set).在我看来,这些情况几乎不可能被发现,直到/除非它们表现为一个错误.
那么,是否有任何最佳实践可以减少我对这个问题的影响?我是否错误地考虑map将一般的Traversable概念化地转换为每个元素,而不是将转换后的元素依次添加到一些新的集合中?.toStream如果我想保留这个心理模型,我应该在映射之前调用所有内容吗?
任何提示/建议将不胜感激.
更新:到目前为止,大多数答案都集中在将总和中包含重复项的机制上.在一般情况下编写代码时,我对所涉及的实践更感兴趣 - 你是否自己在调用之前总是调用toList每个集合map …
我有al:List [Char]我要连接的字符并在一个for循环中作为String返回.
我试过这个
val x: String = for(i <- list) yield(i)
Run Code Online (Sandbox Code Playgroud)
导致
error: type mismatch;
found : List[Char]
required: String
Run Code Online (Sandbox Code Playgroud)
那么如何更改产量的结果类型呢?
谢谢!
我有一个我需要映射到不同类型的地图,结果需要是一个List.我有两种方式(看似)可以实现我想要的,因为在地图上调用地图似乎总是会产生地图.假设我有一些看起来像的地图:
val input = Map[String, List[Int]]("rk1" -> List(1,2,3), "rk2" -> List(4,5,6))
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
val output = input.map{ case(k,v) => (k.getBytes, v) } toList
Run Code Online (Sandbox Code Playgroud)
要么:
val output = input.foldRight(List[Pair[Array[Byte], List[Int]]]()){ (el, res) =>
(el._1.getBytes, el._2) :: res
}
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,我转换了类型,然后调用toList.我假设运行时是类似的O(n*2),所需的空间是n*2.在第二个示例中,我转换类型并一次生成列表.我假设运行时是,O(n)并且所需的空间是n.
我的问题是,这些基本相同还是第二次转换会减少内存/时间/等?此外,在哪里可以找到有关各种scala转换的存储和运行时成本的信息?
提前致谢.
继我提出的另一个问题,Scala 2.8突破之后,我想了解更多关于Scala方法的信息,TraversableLike[A].map其签名如下:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
Run Code Online (Sandbox Code Playgroud)
请注意有关此方法的一些事项:
A,将遍历中的每个转换为a B.That并采用类型的隐式参数CanBuildFrom[Repr, B, That].我可以这样称呼如下:
> val s: Set[Int] = List("Paris", "London").map(_.length)
s: Set[Int] Set(5,6)
Run Code Online (Sandbox Code Playgroud)
什么我不能很好地领会是怎么说的事实That是必然要B(即,它是B的一些集合)是由编译器执行.类型参数看起来独立于上面的签名和特征CanBuildFrom本身的签名:
trait CanBuildFrom[-From, -Elem, +To]
Run Code Online (Sandbox Code Playgroud)
Scala编译器如何确保That不会强制进入没有意义的东西?
> val s: Set[String] = List("Paris", "London").map(_.length) //will not compile
Run Code Online (Sandbox Code Playgroud)
编译器如何确定CanBuildFrom调用范围内的隐式对象是什么?
我正在通过Odersky的ScalaDays 2011主题演讲,当我到达这个特定的行(分配charCode)时,他在非常少的代码行中构建了一个电话号码同义词生成器:
val mnem: Map[Char, String] = // phone digits to mnemonic chars (e.g. '2' -> "ABC")
val charCode: Map[Char, Char] = for ((digit, str) <- mnem; letter <- str)
yield (letter -> digit) // gives ('A', '2'), ('B', '2') etc
Run Code Online (Sandbox Code Playgroud)
为什么是charCode类型Map?
当我在其他例子中产生元组时,我只获得一系列元组 - 而不是地图.例如:
scala> for (i <- 1 to 3) yield (i -> (i+1))
res16: scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,2), (2,3), (3,4))
Run Code Online (Sandbox Code Playgroud)
可以轻松地将其转换为地图toMap(),就像这样......
scala> (for (i <- 1 to …Run Code Online (Sandbox Code Playgroud) 关于Scala中的yield命令和以下示例:
val values = Set(1, 2, 3)
val results = for {v <- values} yield (v * 2)
Run Code Online (Sandbox Code Playgroud)
PS.我知道这个例子没有遵循推荐的功能方式(也就是使用map),但它只是一个例子.