-
Notifications
You must be signed in to change notification settings - Fork 6
/
collection.scala
78 lines (70 loc) · 2.4 KB
/
collection.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package org.cvogt.scala.collection
import scala.collection._
import scala.collection.generic.CanBuildFrom
import scala.annotation.tailrec
object `package`{
implicit class IterableLikeExtensions[A, Repr](coll: IterableLike[A, Repr]){
/** Eliminates duplicates based in the given key function.
There is no guarantee which element stays in case elements are removed.
@param toKey maps elements to a key, which is used for comparison*/
def distinctBy[B, That](toKey: A => B)(implicit bf: CanBuildFrom[Repr, A, That]) = {
val builder = bf(coll.repr)
val keys = mutable.Set[B]()
for(element <- coll){
val key = toKey(element)
if (!keys(key)) {
builder += element
keys += key
}
}
builder.result()
}
}
implicit class GenTraversableOnceExtensions[A](coll: GenTraversableOnce[A]){
/**
Fold while accumulation function returns Some. Stops on first None.
@param initial initual element to start the accumulation on
@param accumulate accumulation function
*/
def foldWhile[A1 >: A](initial: A1)
(accumulate: (A1, A1) => Option[A1]): A1
= foldLeftWhile[A1](initial)(accumulate)
/**
Fold while accumulation function returns Some. Stops on first None.
@param initial initual element to start the accumulation on
@param accumulate accumulation function
*/
def foldLeftWhile[B](initial: B)
(accumulate: (B, A) => Option[B]): B = {
@tailrec
def loop(it: Iterator[A], prev: B): B = {
if(it.hasNext){
val next = it.next
val current = accumulate(prev,next)
if (current.isEmpty) prev
else loop(it,current.get)
} else prev
}
loop(coll.toIterator, initial)
}
/**
Reduce while accumulation function returns Some. Stops on first None.
@param accumulate accumulation function
*/
def reduceWhile[A1 >: A]
(accumulate: (A1, A1) => Option[A1]): A1
= reduceLeftWhile(accumulate)
/**
Reduce while accumulation function returns Some. Stops on first None.
@param accumulate accumulation function
*/
def reduceLeftWhile[A1 >: A]
(accumulate: (A1, A1) => Option[A1]): A1 = {
val it = coll.toIterator
if(it.hasNext)
it.foldWhile[A1](it.next)(accumulate)
else
throw new UnsupportedOperationException("empty.reduceLeftWhile")
}
}
}