相关疑难解决方法(0)

Scala集合如何能够从地图操作中返回正确的集合类型?

注意:这是一个常见问题解答,具体问我所以我可以自己回答,因为这个问题似乎经常出现,我想把它放在一个可以(希望)通过搜索很容易找到的地方

根据我在这里的回答评论提示


例如:

"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通过隐式转换提供.

collections scala

60
推荐指数
2
解决办法
4125
查看次数

如何将Map [Int,Any]转换为Scala中的SortedMap?还是TreeMap?

我想将a转换Map[Int, Any]为a SortedMap或a TreeMap.有一个简单的方法吗?

scala

38
推荐指数
5
解决办法
2万
查看次数

如何使用A值作为地图中的关键字将Seq [A]转换为Map [Int,A]?

我有一个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中高效且优雅地完成这项工作?

scala scala-2.8 scala-collections

37
推荐指数
3
解决办法
4万
查看次数

将可变集合转换为不可变集合

我正在寻找一个转化的最佳途径collection.mutable.Seq[T]collection.immutable.Seq[T].

collections scala

30
推荐指数
3
解决办法
3万
查看次数

映射集合时避免意外删除重复项

我非常喜欢函数式编程概念,但是当我在一个集合中进行映射时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 …

collections functional-programming scala

30
推荐指数
2
解决办法
667
查看次数

列表中的收益字符串[Char]

我有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)

那么如何更改产量的结果类型呢?

谢谢!

scala yield yield-return

29
推荐指数
1
解决办法
3万
查看次数

将Scala映射转换为列表

我有一个我需要映射到不同类型的地图,结果需要是一个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 data-structures

28
推荐指数
2
解决办法
4万
查看次数

Scala 2.8 CanBuildFrom

继我提出的另一个问题,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调用范围内的隐式对象是什么?

generics scala scala-2.8

27
推荐指数
1
解决办法
6163
查看次数

Martin Odersky的ScalaDay 2011年示例:产生一张地图?

我正在通过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

21
推荐指数
3
解决办法
5513
查看次数

Scala:从一种类型的集合到另一种集合

关于Scala中的yield命令和以下示例:

val values = Set(1, 2, 3)
val results = for {v <- values} yield (v * 2)
Run Code Online (Sandbox Code Playgroud)

  • 任何人都可以解释Scala如何知道要收集哪种类型的集合?我知道它是基于,但我如何编写复制产量的代码?
  • 我有什么办法可以改变收藏类型吗?在示例中,我希望结果List类型而不是Set类型.
  • 如果做不到这一点,从一个集合转换到另一个集合的最佳方法是什么?我知道_:*,但由于Set不是Seq,这不起作用.到目前为止我能找到的最好的是val listResults = List()++结果.

    PS.我知道这个例子没有遵循推荐的功能方式(也就是使用map),但它只是一个例子.

  • collections scala yield

    15
    推荐指数
    1
    解决办法
    2万
    查看次数