如何扩展 Scala 列表以不按显式位置而是按给定谓词/条件启用切片

2024-01-17

For

trait Item
case class TypeA(i: Int) extends Item
case class TypeB(i: Int) extends Item

考虑 Scala 项目列表,例如

val myList = List(TypeA(1), TypeB(11), TypeB(12), 
                  TypeA(2), TypeB(21), 
                  TypeA(3), TypeB(31))

目标是定义一个新的slice可以应用到的方法myList并且以谓词或条件作为参数;例如

myList.slice { x => x.isInstanceOf[TypeA] }

会交付

List(List(TypeA(1), TypeB(11), TypeB(12)), 
     List(TypeA(2), TypeB(21)), 
     List(TypeA(3), TypeB(31)))

在此示例中,通过以下方式可以获得相同的结果

myList.slice { case TypeA(x) => x < 10 }

非常感谢。


List已经有一个slice方法 - 它采用开始索引和结束索引之间的元素子集。您正在寻找的是重复应用span method:

def span(p: (A) ⇒ Boolean): (List[A], List[A])

其记录为:

根据谓词将此列表拆分为前缀/后缀对。

注意:c span p 相当于(但可能比)(c takeWhile p, c dropWhile p) 更有效,前提是谓词 p 的计算不会引起任何副作用。

returns:由该列表中元素全部满足 p 的最长前缀和该列表的其余部分组成的对。

您可以通过重复使用此方法和逆谓词来获得所需的内容,并使用额外的逻辑来确保返回的列表都不为空。

import annotation.tailrec

def multiSpan[A](xs: List[A])(splitOn: (A) => Boolean): List[List[A]] = {
  @tailrec
  def loop(xs: List[A], acc: List[List[A]]) : List[List[A]] = xs match {
    case Nil => acc

    case x :: Nil => List(x) :: acc

    case h :: t =>
      val (pre,post) = t.span(!splitOn(_))
      loop(post, (h :: pre) :: acc)
  }
  loop(xs, Nil).reverse
}

UPDATE

根据原始帖子评论中的要求,这里有一个丰富列表的版本,而不是一个独立的方法:

implicit class AddMultispanToList[A](val list: List[A]) extends AnyVal {
  def multiSpan(splitOn: (A) => Boolean): List[List[A]] = {
    @tailrec
    def loop(xs: List[A], acc: List[List[A]]) : List[List[A]] = xs match {
      case Nil => acc

      case x :: Nil => List(x) :: acc

      case h :: t =>
        val (pre,post) = t.span(!splitOn(_))
        loop(post, (h :: pre) :: acc)
    }
    loop(list, Nil).reverse
  }
}

Use as:

myList.multiSpan(_.isInstanceOf[TypeA])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何扩展 Scala 列表以不按显式位置而是按给定谓词/条件启用切片 的相关文章

  • 如果需要,Akka actor 可以从邮箱中删除消息吗?

    例如 如果我想从队列中删除冗余消息 这样当演员收到Connect消息 它应该检查它的邮箱并删除其他Connect消息 以便只进行一个连接而不是多个连接 这样的事情可能吗 是的 您可以将参与者调度程序配置为具有您选择的任何邮箱 因此如果您实现
  • Slick 中的 Scala 枚举(案例对象),良好实践

    假设我有一个代表一组几个有效状态的特征 将对象存储在数据库中是一个好习惯吗 存储 Int 并使用隐式函数 MappedColumnType base Int DoorState 将它们映射到 DoorState 会更好吗 trait Doo
  • 不插入缺失值的Python defaultdict

    So the 默认字典文档 http docs python org 2 library collections html collections defaultdict提到 如果缺少某个项目 则返回的值default factory 插入
  • Numpy:视图与切片复制

    当我进行切片时 发生了意想不到的事情 似乎第一个是视图 但第二个是复制 First 第一个行切片 然后是列切片 看来也是一种看法 gt gt gt a np arange 12 reshape 3 4 gt gt gt a 0 3 2 0
  • 标识符中下划线的 Scala 风格指南

    我已经接受了许多其他语言的观点 即下划线在标识符中具有与字母表一样多的自由度 因此 v and v 另外 尾随下划线是受到推崇的避免与保留关键字产生歧义 class case val abc 0
  • 检查列表中任何相邻整数是否相等

    如果我有一个清单 a 9 4 3 6 4 4 3 6 4 如何检查任意两个相邻元素是否相同 例如 对于索引 4 和 5 处的元素 两者的值为 4 来说 情况都是如此 pairs zip a a 1 Create tuples of neig
  • 为 Apache Spark 示例运行 Cypher (CAPS)

    我知道这是一个广泛的问题 但这会对neo4j不属于某个领域的用户scala编程 我需要使用Apache Spark 项目的 Cypher https github com opencypher cypher for apache spark
  • Scala案例类使用浅拷贝还是深拷贝?

    case class Person var firstname String lastname String val p1 Person amit shah val p2 p1 copy p1 firstname raghu p1 p2 p
  • 如何为每个用户或系统范围配置 Ivy 缓存目录?

    我在用SBT http www scala sbt org 作为我构建 Scala 项目的构建工具 我的问题是 我无法配置 SBT 将依赖项下载到我的用户主目录 因此 我正在寻找每个用户甚至更好的系统范围设置来告诉 SBT 将 Ivy 缓存
  • 在 Plone 4 的集合视图中扩展表列

    集合提供了一个选项来选择要在集合的表视图中显示的列 我们使用 archetypes schemaextender 通过两个字段扩展大多数内容类型 预告图像和预告文本 有没有一种合理的方法来扩展可用表列的列表 有没有一种方法可以在集合的表格视
  • 具有定期更新的静态数据集的结构化流

    将流媒体与静态数据集合并是结构化流媒体的一个重要功能 但在每个批次中 数据集都会从数据源刷新 由于这些源并不总是那么动态 因此在指定的时间段 或批次数 内缓存静态数据集会提高性能 在指定的时间段 批次数之后 将从源重新加载数据集 否则从缓存
  • R:重新列出平面列表

    这个问题 https stackoverflow com questions 8139677有一个很好的解决方案 可以在保留列表数据类型的同时展平列表 其中unlist才不是 flatten function x unlist vector
  • 如何强制 Spark 执行代码?

    我如何强制 Spark 执行对 map 的调用 即使它认为由于其惰性求值而不需要执行它 我试过把cache 与地图调用 但这仍然没有解决问题 我的地图方法实际上将结果上传到 HDFS 所以 它并非无用 但 Spark 认为它是无用的 简短回
  • SBT - 使用汇编时多项目合并策略和构建 sbt 结构

    我有一个由多个较小项目组成的项目 其中一些项目相互依赖 例如 有一个依赖于 commons 项目的实用程序项目 其他项目可能依赖于公用事业或公共设施 也可能不依赖于两者 在 build sbt 中 我在文件末尾有程序集合并策略 以及程序集中
  • 发送 FakeRequest 时如何为 akka.stream.Materializer 提供隐式值?

    我正在尝试理解下面看到的错误 并学习如何修复它 could not find implicit value for parameter materializer akka Stream Materializer val fut Future
  • 一起调用distinct和map会在spark库中抛出NPE

    我不确定这是否是一个错误 所以如果你这样做 d spark RDD String d distinct map x gt d filter equals x 您将获得 Java NPE 但是如果你做了一个collect之后立马distinc
  • 带有泛型参数的抽象类的 JsonFormat

    我正在尝试为具有通用参数的抽象类编写 JsonFormat 如下所示 abstract class Animal A def data A def otherStuff String stuff case class CatData cat
  • 这是一种在 Akka FSM 中内部监视到第一个状态的转换的方法吗?

    考虑从状态 Idle 开始的 FSM actor startWith Idle IdleData 我想监视到第一个状态的转换 从无状态 I tried onTransition case gt Idle gt Wasn t called 根
  • 如何在Python中手动对数字列表进行排序?

    规格 Ubuntu 13 04 Python 3 3 1 背景 Python的初学者 遇到了这个 手动排序 问题 我被要求做的事情 让用户输入 3 个数值并将它们存储在 3 个不同的变量中 不使用列表或排序算法 手动将这 3 个数字从小到大
  • 将二进制数转换为包含每个二进制数的数组

    我试图将二进制值转换为每个 1 0 的列表 但我得到默认的二进制值而不是列表 我有一个字符串 我将每个字符转换为二进制 它给了我一个列表 其中每个字符都有一个字符串 现在我试图将每个字符串拆分为值为 0 1 的整数 但我什么也得不到 if

随机推荐