加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 当将`map`应用于`Set`时,你有时希望结果不是一组而是忽

发布时间:2020-12-16 08:54:40 所属栏目:安全 来源:网络整理
导读:或者如何在映射Set时避免意外删除重复项? 这是我经常犯的错误.看下面的代码: def countSubelements[A](sl: Set[List[A]]): Int = sl.map(_.size).sum 该函数应计算所有包含列表的累计大小.问题是在将列表映射到它们的长度之后,结果仍然是Set,并且所有大小
或者如何在映射Set时避免意外删除重复项?

这是我经常犯的错误.看下面的代码:

def countSubelements[A](sl: Set[List[A]]): Int = sl.map(_.size).sum

该函数应计算所有包含列表的累计大小.问题是在将列表映射到它们的长度之后,结果仍然是Set,并且所有大小为1的列表都减少为单个代表.

这只是我有这个问题吗?我能做些什么来防止这种情况发生?我想我喜欢有两种方法mapToSet和mapToSeq for Set.但是没有办法强制执行此操作,有时您不会在本地注意到您正在使用Set.

也许你甚至有可能为Seq编写代码,而另一个类中的某些东西发生了变化,底层对象变成了Set?

也许是最好的做法,不要让这种情况出现?

远程编辑破坏了我的代码

想象一下以下情况:

val totalEdges = graph.nodes.map(_.getEdges).map(_.size).sum / 2

您从图形中获取Node对象的集合,使用它们获取它们的相邻边缘并对它们求和.如果graph.nodes返回Seq,则此方法有效.

如果有人决定让Graph将其节点作为Set返回,它就会中断;没有这个代码看起来可疑(至少不是我,你期望每个集合可能最终成为一个集?)并且没有触及它.

解决方法

如果想要一个Seq并得到一个Set,似乎会有很多可能的“陷阱”.方法实现可以依赖于对象的类型和(带有重载)参数,这并不奇怪.使用Scala implicits,该方法甚至可以依赖于预期的返回类型.

防止意外的方法是明确标记类型.例如,使用返回类型注释方法,即使它不是必需的.至少这样,如果graph.nodes的类型从Seq更改为Set,程序员就会意识到存在潜在的破坏.

对于您的具体问题,为什么不定义自己的mapToSeq方法,

scala> def mapToSeq[A,B](t: Traversable[A])(f: A => B): Seq[B] =
           t.map(f)(collection.breakOut)
mapToSeq: [A,B](t: Traversable[A])(f: A => B)Seq[B]

scala> mapToSeq(Set(Seq(1),Seq(1,2)))(_.sum)
res1: Seq[Int] = Vector(1,3)

scala> mapToSeq(Seq(Seq(1),2)))(_.sum)
res2: Seq[Int] = Vector(1,3)

使用breakOut:CanBuildFrom的优点是从Set到Seq的转换没有额外的开销.

您可以使用pimp my library pattern使mapToSeq看起来是Severs和Set继承的Traversable特征的一部分.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读