scala:向List添加方法?

时间:2011-08-07 20:58:46

标签: scala

我想知道如何在列表中添加'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)
  }
}

3 个答案:

答案 0 :(得分:9)

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

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它(除非您在定义它的同一范围内使用它)。

答案 1 :(得分:3)

正如 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)
    }
}

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

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

如果您对它是如何工作感到好奇,只需删除implicit关键字并显式调用list2richList转换(这是编译器在使用implicit时透明地执行的操作)。< / p>

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

答案 2 :(得分:1)

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)}