Skip to content

Instantly share code, notes, and snippets.

@vlfig
Created August 27, 2012 16:55
Show Gist options
  • Save vlfig/3490333 to your computer and use it in GitHub Desktop.
Save vlfig/3490333 to your computer and use it in GitHub Desktop.
List's span variations
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