Created
August 27, 2012 16:55
-
-
Save vlfig/3490333 to your computer and use it in GitHub Desktop.
List's span variations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.collection.mutable.ListBuffer | |
/** | |
* Span-like inclusive methods for slicing list based on element predicates. | |
* @author Vasco Figueira | |
* @author Peter Empen | |
*/ | |
class ListSpanVariations[A](l: List[A]) { | |
/** | |
* Original span implementation | |
*/ | |
def span(p: A => Boolean): (List[A], List[A]) = { | |
val b = new ListBuffer[A] | |
var these = l | |
while (!these.isEmpty && p(these.head)) { | |
b += these.head | |
these = these.tail | |
} | |
(b.toList, these) | |
} | |
/** | |
* Like span in List but including the first element for which | |
* p is false | |
* | |
* Adds one extra var | |
*/ | |
def spanInclusive(p: A => Boolean): (List[A], List[A]) = { | |
val b = new ListBuffer[A] | |
var these = l | |
var continue = true | |
while (!these.isEmpty && continue) { | |
b += these.head | |
continue = p(these.head) | |
these = these.tail | |
} | |
(b.toList, these) | |
} | |
/** | |
* The same effect but using List's span | |
* Uses boolean; works for including one elem only | |
*/ | |
def spanInclusive2(p: A => Boolean): (List[A], List[A]) = { | |
var virgin = true | |
l span { e => | |
if (!p(e) && virgin == true) { | |
virgin = false | |
true | |
} else { | |
virgin | |
} | |
} | |
} | |
/** | |
* Uses integer variable. Includes one more. | |
*/ | |
def spanPlus1(p: A => Boolean): (List[A], List[A]) = { | |
var found = 0 | |
l span { e => | |
if (!p(e) || found > 0) found += 1 | |
found <= 1 | |
} | |
} | |
/** | |
* Uses integer variable. Includes two more. | |
*/ | |
def spanPlus2(p: A => Boolean): (List[A], List[A]) = { | |
var found = 0 | |
l span { e => | |
if (!p(e) || found > 0) found += 1 | |
found <= 2 | |
} | |
} | |
/** | |
* Uses integer variable. Can include n more. | |
*/ | |
def spanPlusN(n: Int)(p: A => Boolean): (List[A], List[A]) = { | |
var found = 0 | |
l span { e => | |
if (!p(e) || found > 0) found += 1 | |
found <= n | |
} | |
} | |
} | |
object ListSpanVariations { | |
implicit def listToListSpanVariations[A](l: List[A]): ListSpanVariations[A] = { | |
new ListSpanVariations(l) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment