繁体   English   中英

scala:向List添加方法?

[英]scala: adding a method to List?

我想知道如何在列表中添加'partitionCount'方法,例如:(未经过测试,无耻地基于List.scala):

我是否必须创建自己的子类和隐式类型转换器?

(我最初的尝试有很多问题,所以这里有一个基于@Easy的答案):

class MyRichList[A](targetList: List[A]) {
  def partitionCount(p: A => Boolean): (Int, Int) = {
    var btrue = 0
    var bfalse = 0
    var these = targetList
    while (!these.isEmpty) {
      if (p(these.head)) { btrue += 1 }  else { bfalse += 1 }
      these = these.tail
    }
    (btrue, bfalse)
  }
}

这是一个更适合Seq [...]的通用版本:

implicit def seqToRichSeq[T](s: Seq[T]) = new MyRichSeq(s)

class MyRichList[A](targetList: List[A]) {
  def partitionCount(p: A => Boolean): (Int, Int) = {
    var btrue = 0
    var bfalse = 0
    var these = targetList
    while (!these.isEmpty) {
      if (p(these.head)) { btrue += 1 }  else { bfalse += 1 }
      these = these.tail
    }
    (btrue, bfalse)
  }
}

你可以像这样使用隐式转换:

implicit def listToMyRichList[T](l: List[T]) = new MyRichList(l)

class MyRichList[T](targetList: List[T]) {
    def partitionCount(p: T => Boolean): (Int, Int) = ...
}

而不是this你需要使用targetList 您不需要扩展List 在这个例子中,我创建了隐式使用的简单包装器MyRichList

您可以通过为Traversable定义包装器来进一步概括包装器,以便它可以用于其他集合类型,而不仅仅适用于List

implicit def listToMyRichTraversable[T](l: Traversable[T]) = new MyRichTraversable(l)

class MyRichTraversable[T](target: Traversable[T]) {
    def partitionCount(p: T => Boolean): (Int, Int) = ...
}

另请注意,只有在范围内时才会使用隐式转换。 这意味着,您需要import它(除非您在已定义它的同一范围内使用它)。

正如Easy Angel已经指出的那样,使用隐式转换:

implicit def listTorichList[A](input: List[A]) = new RichList(input)

class RichList[A](val source: List[A]) {

    def partitionCount(p: A => Boolean): (Int, Int) = {
        val partitions = source partition(p)
        (partitions._1.size, partitions._2.size)
    }
}

另请注意,您可以根据partinion轻松定义partitionCount 然后你可以简单地使用:

val list = List(1, 2, 3, 5, 7, 11)
val (odd, even) = list partitionCount {_ % 2 != 0}

如果你很好奇它是如何工作的,只需删除implicit关键字并显式调用list2richList转换(这是编译器在使用implicit时对你透明的做法)。

val (odd, even) = list2richList(list) partitionCount {_ % 2 != 0}

Easy Angel是对的,但这种方法似乎很无用。 你已经count了以获得“肯定”的数量,当然“负数”的数量是size减去count

但是,为了贡献积极的东西,这里是原始方法的更多功能版本:

def partitionCount[A](iter: Traversable[A], p: A => Boolean): (Int, Int) =
   iter.foldLeft ((0,0)) { ((x,y), a) => if (p(a)) (x + 1,y) else (x, y + 1)}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM