scala: adding a method to List?

后端 未结 3 1712
深忆病人
深忆病人 2021-01-13 11:55

I was wondering how to go about adding a \'partitionCount\' method to Lists, e.g.: (not tested, shamelessly based on List.scala):

Do I have to create my own sub-clas

相关标签:
3条回答
  • 2021-01-13 12:36

    Easy Angel is right, but the method seems pretty useless. You have already count in order to get the number of "positives", and of course the number of "negatives" is size minus count.

    However, to contribute something positive, here a more functional version of your original method:

    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)}
    
    0 讨论(0)
  • 2021-01-13 12:42

    As already pointed out by Easy Angel, use implicit conversion:

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

    Also note that you can easily define partitionCount in terms of partinion. Then you can simply use:

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

    If you are curious how it works, just remove implicit keyword and call the list2richList conversion explicitly (this is what the compiler does transparently for you when implicit is used).

    val (odd, even) = list2richList(list) partitionCount {_ % 2 != 0}
    
    0 讨论(0)
  • 2021-01-13 12:50

    You can use implicit conversion like this:

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

    and instead of this you need to use targetList. You don't need to extend List. In this example I create simple wrapper MyRichList that would be used implicitly.

    You can generalize wrapper further, by defining it for Traversable, so that it will work for may other collection types and not only for Lists:

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

    Also note, that implicit conversion would be used only if it's in scope. This means, that you need to import it (unless you are using it in the same scope where you have defined it).

    0 讨论(0)
提交回复
热议问题