在Java 1.6中,引入了NavigableMap(和NavigableSet)接口,并更新了TreeMap以实现新接口.除此之外,NavigableMap对于询问诸如"集合中哪个元素最接近X?"之类的问题非常有用(请参阅FrançoisSarradin的这篇优秀博客文章,以获得示例和讨论).
我希望在Scala 2.8的TreeMap实现中找到类似的东西,但唉,它似乎并非如此(至少,它并不明显).是否有另一个类似于Java的NavigableMap的Scala类或特征?如果没有,是否有一些简单的Scala习语可以用来实现类似的东西?
我意识到我可以使用Java的TreeMap,但我想留在Scala集合框架内(如果只是为了简单).
我有一个模型,它有一些Option字段,其中包含另一个Option字段.例如:
case class First(second: Option[Second], name: Option[String])
case class Second(third: Option[Third], title: Option[String])
case class Third(numberOfSmth: Option[Int])
Run Code Online (Sandbox Code Playgroud)
我从外部JSON收到这些数据,有时这些数据可能包含null,这就是这种模型设计的原因.
所以问题是:获得最深领域的最佳方法是什么?
First.get.second.get.third.get.numberOfSmth.get
Run Code Online (Sandbox Code Playgroud)
上面的方法看起来很丑陋,如果其中一个对象是None,可能会导致异常.我正在寻找Scalaz lib,但没有找到更好的方法来做到这一点.
有任何想法吗?提前致谢.
有许多很棒的教程和帖子,其中包含更简单的Lens方法,例如Cleaner更新嵌套结构的方法 ; 任何人都可以提供这三种其他方法的示例用途吗?谢谢.
我刚刚在Coursera完成了Martin Odersky的scala课程.Scala是我的第一个FP语言,我对限制可变状态的想法很兴奋.这允许更容易的并发性并且还使代码超级可维护.
在学习所有这些的同时,我意识到你可以保证对象的可变性,只要它没有可变变量并且只引用了不可变对象.所以现在我可以通过创建一个新状态而不是修改旧状态来做任何事情,尽可能使用尾递归.
大.所以我到目前为止只能做到这一点.在某些时候,我的应用程序需要能够修改一些现有的状态.我知道在这一点上放入并发控制的地方,锁定,等等等等.我仍然默认使用我一直使用的标准多线程并发控制.
哦斯卡拉社区,还有更好的方法吗?莫纳德也许?
编辑:这个问题有点笼统,所以我想给出一个用例:我有一个机器学习算法,可以存储几个数据集合.它们具有返回数据(训练等)的更新表示的函数,所有函数都是不可变的.最终,我可以将这个返回更新状态模式保持在运行模拟的实际对象上.它具有可变的状态并保存对集合的引用.我可能想分发到多核或多系统.
我对透镜的基本理解是,“透镜是表示复杂类型与其组成部分之一之间的映射的值。该映射以两种方式工作\xe2\x80\x94我们可以获取或“访问”组成部分并设置或“变异” “ 它”
\n\n我在设计机器学习库(神经网络)时遇到了这一点,它需要保留一个大的参数数据结构,其中的参数组需要在算法的不同阶段进行更新。我想创建整个参数数据结构不可变,但是更改一组参数需要复制所有参数,并重新创建一个新的数据结构,这听起来效率很低。毫不奇怪其他人 认为。有些人建议使用镜头,从某种意义上说,它可以让您修改不可变的数据结构。而其他一些人建议只使用可变的这些。不幸的是,我找不到任何关于比较这两种范式的内容,包括速度、空间、代码复杂性等。
\n\n现在的问题是,使用透镜与可变设计的优点/缺点是什么?
\n以下类具有辅助构造函数,以不可变的方式更改一个属性.
class AccUnit(size: Long, start: Date, direction:Direction, protocol:String) {
def this(size:Long, that:AccUnit) {this(size, that.start, that.direction, that.protocol)}
}
Run Code Online (Sandbox Code Playgroud)
编译器返回错误:
AccUnit.scala:26: error: value start is not a member of trafacct.AccUnit
def this(size:Long, that:AccUnit) {this(size, that.start, that.direction, that.protocol)}
^
AccUnit.scala:26: error: value direction is not a member of trafacct.AccUnit
def this(size:Long, that:AccUnit) {this(size, that.start, that.direction, that.protocol)}
^
AccUnit.scala:26: error: value protocol is not a member of trafacct.AccUnit
def this(size:Long, that:AccUnit) {this(size, that.start, that.direction, that.protocol)}
Run Code Online (Sandbox Code Playgroud)
为什么会这样认为,没有这样的成员?
在我看来,这个概念已经足够可以理解了.
我想做这样的事情(像java一样):
trait PersonInfo {
var name: Option[String] = None
var address: Option[String] = None
// plus another 30 var, for example
}
case class Person() extends PersonInfo
object TestObject {
def main(args: Array[String]): Unit = {
val p = new Person()
p.name = Some("someName")
p.address = Some("someAddress")
}
}
Run Code Online (Sandbox Code Playgroud)
所以我可以更改名称,地址等...
这很好用,但问题是,在我的程序中,我最终将所有内容都视为变量.据我所知,val在scala中是"首选".val如何在这种类型的示例中工作,而不必在每次更改其中一个参数时重写所有30多个参数?
也就是说,我可以
trait PersonInfo {
val name: Option[String]
val address: Option[String]
// plus another 30 val, for example
}
case class Person(name: Option[String]=None, address: Option[String]=None, ...plus another 30.. ) …Run Code Online (Sandbox Code Playgroud) 我有以下类:
class Player(val name: String, val onField: Boolean, val draft: Int, val perc: Int, val height: Int, val timePlayed: Int) {
override def toString: String = name
Run Code Online (Sandbox Code Playgroud)
}
我正在努力做到
def play(team: List[Player]): List[Player] =
team map (p => new Player(p.name, p.onField, p.draft, p.perc, p.height, p.timePlayed + 1))
Run Code Online (Sandbox Code Playgroud)
这实际上是将字段"timePlayed"递增1,并返回播放器的新"列表".
有更方便的方法吗?也许:
def play(team: List[Player]): List[Player] =
team map (p => p.timeIncremented())
Run Code Online (Sandbox Code Playgroud)
我的问题是如何以更方便的方式实现timeIncremented()?所以我不必这样做:
new Player(p.name, p.onField, p.draft, p.perc, p.height, p.timePlayed + 1)
Run Code Online (Sandbox Code Playgroud)
谢谢!