过滤器后创建实例类型

Creating instance type after filter

我有一个简单的 class 扩展了 IndexedSeq[MyType]

class MyClass(someName: String, values: Iterable[MyType]) extends IndexedSeq[MyType] {
  val name = someName
  val rows = values.toVector
  ....
}

这很好用,允许我调用此对象、过滤器、地图等的所有标准收集方法,并将结果作为 IndexedSeq[MyType] 返回给我。

我想要的是将结果作为 MyClass 的新实例或无样板的方式返回,这样我就不需要每次创建新 MyClass 时都需要额外的手动步骤。例如:

val results = myClassInstance.filter(t => t)
val newMyClass = new MyClass(myClassInstance.name, results)

鉴于我需要访问原始 myClassInstance 以将名称值从它复制到新对象,是否有任何方法可以简化并执行如下操作。

val newMyClass = myClassInstance.filter(t => t).toMyClass

谢谢

你确定要继承IndexedSeq吗?

如果您在 class 中只需要 filtermap 函数,您可以实现它们,而无需覆盖 IndexedSeq

class MyClass(name: String, values: Iterable[MyType]) {

    def filter(f: MyType => Boolean): MyClass = {
        new MyClass(name, values.filter(f))
    }

    def map(f: MyType => MyType): MyClass = {
        new MyClass(name, values.map(f))
    }

}

或者如果你真的真的需要覆盖 IndexedSeq,你可以在你的 class

中添加显式过滤方法
class MyClass(name: String, values: Iterable[MyType]) extends IndexedSeq[MyClass] {

    def filterClass(f: MyType => Boolean): MyClass = {
        new MyClass(name, values.filter(f))
    }

}

或其他选择

class MyClass(name: String, values: Iterable[MyType]) extends IndexedSeq[MyClass] {

    def copyWith(f: Iterable[MyType] => Iterable[MyType]): MyClass = {
        new MyClass(name, f(values))
    }

}

MyClass.copyWith(_.filter(...))
MyClass.copyWith(_.filterNot(...))
MyClass.copyWith(_.map(...))

我已经通过扩展 IndexedSeqLike[DataRow, DataView] 并在伴随对象中实现构建器找到了解决方案。到目前为止,这似乎完全符合我的要求,无需直通调用。

class MyClass(someName: String, values: Iterable[MyType]) 
  extends IndexedSeq[MyType] 
  with IndexedSeqLike[MyType, MyClass] {

  val name = someName
  val rows = values.toVector

  // Supply a builder method which will get used on filter, reverse etc,
  override def newBuilder: mutable.Builder[MyType, MyClass] =
    MyClass.newBuilder(name)

  ....
}

然后在伴随对象中,添加以下...

object MyClass {

  // Builder for a new MyClass instance.
  def newBuilder(name: String): mutable.Builder[MyType, MyClass] =
    Vector.newBuilder[MyType] mapResult (vector => new MyClass(name, vector))
}

现在按要求进行以下工作:

val filteredData: MyClass = myClass.filter(f => f)
val reversedData: MyClass = myClass.reverse