/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ package scala import scala.collection.mutable.ListBuffer import Predef._ /** This object provides methods for creating specialized lists, and for * transforming special kinds of lists (e.g. lists of lists). * * @author Martin Odersky and others * @version 1.0, 15/07/2003 */ object List { /** Create a list with given elements. * * @param xs the elements to put in the list * @return the list containing elements xs. */ def apply[A](xs: A*): List[A] = xs.toList /** for unapply matching */ def unapplySeq[A](x: List[A]): Some[List[A]] = Some(x) /** Create a sorted list of all integers in a range. * * @param from the start value of the list * @param end the end value of the list * @return the sorted list of all integers in range [from;end). */ def range(from: Int, end: Int): List[Int] = range(from, end, 1) /** Create a sorted list of all integers in a range. * * @param from the start value of the list * @param end the end value of the list * @param step the increment value of the list * @return the sorted list of all integers in range [from;end). */ def range(from: Int, end: Int, step: Int): List[Int] = { val b = new ListBuffer[Int] var i = from while (i < end) { b += i i += step } b.toList } /** Create a sorted list of all integers in a range. * * @param from the start value of the list * @param end the end value of the list * @param step the increment function of the list * @return the sorted list of all integers in range [from;end). */ def range(from: Int, end: Int, step: Int => Int): List[Int] = { val b = new ListBuffer[Int] var i = from while (i < end) { b += i i += step(i) } b.toList } /** Create a list containing several copies of an element. * * @param n the length of the resulting list * @param elem the element composing the resulting list * @return a list composed of n elements all equal to elem */ def make[A](n: Int, elem: A): List[A] = { val b = new ListBuffer[A] var i = 0 while (i < n) { b += elem i += 1 } b.toList } /** Create a list by applying a function to successive integers. * * @param n the length of the resulting list * @param maker the procedure which, given an integer n, * returns the nth element of the resulting list, where * n is in interval [0;n). * @return the list obtained by applying the maker function to * successive integers from 0 to n (exclusive). */ def tabulate[A](n: Int, maker: Int => A): List[A] = { val b = new ListBuffer[A] var i = 0 while (i < n) { b += maker(i) i += 1 } b.toList } /** Concatenate all the elements of a given list of lists. * * @param xss the list of lists that are to be concatenated * @return the concatenation of all the lists */ def flatten[A](xss: List[List[A]]): List[A] = concat(xss: _*) /** Concatenate all the argument lists into a single list. * * @param xss the lists that are to be concatenated * @return the concatenation of all the lists */ def concat[A](xss: List[A]*): List[A] = { val b = new ListBuffer[A] for (xs <- xss) { var xc = xs while (!xc.isEmpty) { b += xc.head xc = xc.tail } } b.toList } /** Transforms a list of pair into a pair of lists. * * @param xs the list of pairs to unzip * @return a pair of lists: the first list in the pair contains the list */ def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = { val b1 = new ListBuffer[A] val b2 = new ListBuffer[B] var xc = xs while (!xc.isEmpty) { b1 += xc.head._1 b2 += xc.head._2 xc = xc.tail } (b1.toList, b2.toList) } /** Converts an iterator to a list. * * @param it the iterator to convert * @return a list that contains the elements returned by successive * calls to it.next */ def fromIterator[A](it: Iterator[A]): List[A] = it.toList /** Converts an array into a list. * * @param arr the array to convert * @return a list that contains the same elements than arr * in the same order */ def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length) /** Converts a range of an array into a list. * * @param arr the array to convert * @param start the first index to consider * @param len the lenght of the range to convert * @return a list that contains the same elements than arr * in the same order */ def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = { var res: List[A] = Nil var i = start + len while (i > start) { i -= 1 res = arr(i) :: res } res } /** Parses a string which contains substrings separated by a * separator character and returns a list of all substrings. * * @param str the string to parse * @param separator the separator character * @return the list of substrings */ def fromString(str: String, separator: Char): List[String] = { var words: List[String] = Nil var pos = str.length() while (pos > 0) { val pos1 = str.lastIndexOf(separator, pos - 1) if (pos1 + 1 < pos) words = str.substring(pos1 + 1, pos) :: words pos = pos1 } words } /** Returns the given string as a list of characters. * * @param str the string to convert. * @return the string as a list of characters. * @deprecated use str.toList instead */ @deprecated def fromString(str: String): List[Char] = str.toList /** Returns the given list of characters as a string. * * @param xs the list to convert. * @return the list in form of a string. */ def toString(xs: List[Char]): String = { val sb = new StringBuilder() var xc = xs while (!xc.isEmpty) { sb.append(xc.head) xc = xc.tail } sb.toString() } /** Like xs map f, but returns xs unchanged if function * f maps all elements to themselves. * * @param xs ... * @param f ... * @return ... */ def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = { def loop(ys: List[A]): List[A] = if (ys.isEmpty) xs else { val head0 = ys.head val head1 = f(head0) if (head1 eq head0) { loop(ys.tail) } else { val ys1 = head1 :: mapConserve(ys.tail)(f) if (xs eq ys) ys1 else { val b = new ListBuffer[A] var xc = xs while (xc ne ys) { b += xc.head xc = xc.tail } b.prependToList(ys1) } } } loop(xs) } /** Returns the list resulting from applying the given function f * to corresponding elements of the argument lists. * * @param f function to apply to each pair of elements. * @return [f(a0,b0), ..., f(an,bn)] if the lists are * [a0, ..., ak], [b0, ..., bl] and * n = min(k,l) */ def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = { val b = new ListBuffer[C] var xc = xs var yc = ys while (!xc.isEmpty && !yc.isEmpty) { b += f(xc.head, yc.head) xc = xc.tail yc = yc.tail } b.toList } /** Returns the list resulting from applying the given function * f to corresponding elements of the argument lists. * * @param f function to apply to each pair of elements. * @return [f(a0,b0,c0), * ..., f(an,bn,cn)] * if the lists are [a0, ..., ak], * [b0, ..., bl], * [c0, ..., cm] and * n = min(k,l,m) */ def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = { val b = new ListBuffer[D] var xc = xs var yc = ys var zc = zs while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) { b += f(xc.head, yc.head, zc.head) xc = xc.tail yc = yc.tail zc = zc.tail } b.toList } /** Tests whether the given predicate p holds * for all corresponding elements of the argument lists. * * @param p function to apply to each pair of elements. * @return (p(a0,b0) && * ... && p(an,bn))] * if the lists are [a0, ..., ak]; * [b0, ..., bl] * and n = min(k,l) */ def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { var xc = xs var yc = ys while (!xc.isEmpty && !yc.isEmpty) { if (!f(xc.head, yc.head)) return false xc = xc.tail yc = yc.tail } true } /** Tests whether the given predicate p holds * for some corresponding elements of the argument lists. * * @param p function to apply to each pair of elements. * @return n != 0 && (p(a0,b0) || * ... || p(an,bn))] if the lists are * [a0, ..., ak], * [b0, ..., bl] and * n = min(k,l) */ def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = { var xc = xs var yc = ys while (!xc.isEmpty && !yc.isEmpty) { if (f(xc.head, yc.head)) return true xc = xc.tail yc = yc.tail } false } /** Transposes a list of lists. * pre: All element lists have the same length. * * @param xss the list of lists * @return the transposed list of lists */ def transpose[A](xss: List[List[A]]): List[List[A]] = if (xss.head.isEmpty) List() else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail)) /** Lists with ordered elements are ordered implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { case y1: List[a] => compareLists(x, y1); case _ => -(y compare x) } private def compareLists(xs: List[a], ys: List[a]): Int = { if (xs.isEmpty && ys.isEmpty) 0 else if (xs.isEmpty) -1 else if (ys.isEmpty) 1 else { val s = xs.head compare ys.head; if (s != 0) s else compareLists(xs.tail, ys.tail) } } } */ } /** A class representing an ordered collection of elements of type * a. This class comes with two implementing case * classes scala.Nil and scala.:: that * implement the abstract members isEmpty, * head and tail. * * @author Martin Odersky and others * @version 1.0, 16/07/2003 */ sealed abstract class List[+A] extends Seq[A] { /** Returns true if the list does not contain any elements. * @return true, iff the list is empty. */ override def isEmpty: Boolean /** Returns this first element of the list. * * @return the first element of this list. * @throws Predef.NoSuchElementException if the list is empty. */ def head: A /** Returns this list without its first element. * * @return this list without its first element. * @throws Predef.NoSuchElementException if the list is empty. */ def tail: List[A] /**

* Add an element x at the beginning of this list. *

* * @param x the element to append. * @return the list with x appended at the beginning. * @ex 1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3) */ def ::[B >: A] (x: B): List[B] = new scala.::(x, this) /**

* Returns a list resulting from the concatenation of the given * list prefix and this list. *

* * @param prefix the list to concatenate at the beginning of this list. * @return the concatenation of the two lists. * @ex List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4) */ def :::[B >: A](prefix: List[B]): List[B] = if (isEmpty) prefix else { val b = new ListBuffer[B] var those = prefix while (!those.isEmpty) { b += those.head those = those.tail } b.prependToList(this) } /** Reverse the given prefix and append the current list to that. * This function is equivalent to an application of reverse * on the prefix followed by a call to :::, but more * efficient (and tail recursive). * * @param prefix the prefix to reverse and then prepend * @return the concatenation of the reversed prefix and the current list. */ def reverse_:::[B >: A](prefix: List[B]): List[B] = prefix match { case Nil => this case head :: tail => (head :: this).reverse_:::(tail) } /** Returns the number of elements in the list. * * @return the number of elements in the list. */ def length: Int = { var these = this var len = 0 while (!these.isEmpty) { len += 1 these = these.tail } len } /** Creates a list with all indices in the list. This is * equivalent to a call to List.range(0, xs.length). * * @return a list of all indices in the list. */ def indices: List[Int] = { val b = new ListBuffer[Int] var i = 0 var these = this while (!these.isEmpty) { b += i i += 1 these = these.tail } b.toList } /** Returns the elements in the list as an iterator * * @return an iterator on the list elements. */ override def elements: Iterator[A] = new Iterator[A] { var these = List.this def hasNext: Boolean = !these.isEmpty def next: A = if (!hasNext) throw new NoSuchElementException("next on empty Iterator") else { val result = these.head; these = these.tail; result } override def toList: List[A] = these } /** Overrides the method in Iterable for efficiency. * * @return the list itself */ override def toList: List[A] = this /** Returns the list without its last element. * * @return the list without its last element. * @throws Predef.UnsupportedOperationException if the list is empty. */ def init: List[A] = if (isEmpty) throw new UnsupportedOperationException("Nil.init") else { val b = new ListBuffer[A] var elem = head var next = tail while (!next.isEmpty) { b += elem elem = next.head next = next.tail } b.toList } /** Returns the last element of this list. * * @return the last element of the list. * @throws Predef.UnsupportedOperationException if the list is empty. */ override def last: A = if (isEmpty) throw new Predef.NoSuchElementException("Nil.last") else if (tail.isEmpty) head else tail.last /** Returns the n first elements of this list, or else the whole * list, if it has less than n elements. * * @param n the number of elements to take. * @return the n first elements of this list. */ override def take(n: Int): List[A] = { val b = new ListBuffer[A] var i = 0 var these = this while (!these.isEmpty && i < n) { i += 1 b += these.head these = these.tail } if (these.isEmpty) this else b.toList } override def slice(from : Int, until : Int) : List[A] = drop(from).take(until - from) /** Returns the list without its n first elements. * If this list has less than n elements, the empty list is returned. * * @param n the number of elements to drop. * @return the list without its n first elements. */ override def drop(n: Int): List[A] = if (isEmpty || n <= 0) this else (tail drop (n-1)) /** Returns the rightmost n elements from this list. * * @param n the number of elements to take * @return the suffix of length n of the list */ def takeRight(n: Int): List[A] = { def loop(lead: List[A], lag: List[A]): List[A] = lead match { case Nil => lag case _ :: tail => loop(tail, lag.tail) } loop(drop(n), this) } /** Returns the list wihout its rightmost n elements. * * @param n the number of elements to take * @return the suffix of length n of the list */ def dropRight(n: Int): List[A] = { def loop(lead: List[A], lag: List[A]): List[A] = lead match { case Nil => Nil case _ :: tail => lag.head :: loop(tail, lag.tail) } loop(drop(n), this) } /** Split the list at a given point and return the two parts thus * created. * * @param n the position at which to split * @return a pair of lists composed of the first n * elements, and the other elements. */ def splitAt(n: Int): (List[A], List[A]) = { val b = new ListBuffer[A] var i = 0 var these = this while (!these.isEmpty && i < n) { i += 1 b += these.head these = these.tail } (b.toList, these) } /** Returns the longest prefix of this list whose elements satisfy * the predicate p. * * @param p the test predicate. * @return the longest prefix of this list whose elements satisfy * the predicate p. */ override def takeWhile(p: A => Boolean): List[A] = { val b = new ListBuffer[A] var these = this while (!these.isEmpty && p(these.head)) { b += these.head these = these.tail } b.toList } /** Returns the longest suffix of this list whose first element * does not satisfy the predicate p. * * @param p the test predicate. * @return the longest suffix of the list whose first element * does not satisfy the predicate p. */ override def dropWhile(p: A => Boolean): List[A] = if (isEmpty || !p(head)) this else tail dropWhile p /** Returns the longest prefix of the list whose elements all satisfy * the given predicate, and the rest of the list. * * @param p the test predicate * @return a pair consisting of the longest prefix of the list whose * elements all satisfy p, and the rest of the list. */ def span(p: A => Boolean): (List[A], List[A]) = { val b = new ListBuffer[A] var these = this while (!these.isEmpty && p(these.head)) { b += these.head these = these.tail } (b.toList, these) } /** Like span but with the predicate inverted. */ def break(p: A => Boolean): (List[A], List[A]) = span { x => !p(x) } /** Returns the n-th element of this list. The first element * (head of the list) is at position 0. * * @param n index of the element to return * @return the element at position n in this list. * @throws Predef.NoSuchElementException if the list is too short. */ def apply(n: Int): A = drop(n).head /** Returns the list resulting from applying the given function f to each * element of this list. * * @param f function to apply to each element. * @return [f(a0), ..., f(an)] if this list is [a0, ..., an]. */ final override def map[B](f: A => B): List[B] = { val b = new ListBuffer[B] var these = this while (!these.isEmpty) { b += f(these.head) these = these.tail } b.toList } /** Apply a function to all the elements of the list, and return the * reversed list of results. This is equivalent to a call to map * followed by a call to reverse, but more efficient. * * @param f the function to apply to each elements. * @return the reversed list of results. */ def reverseMap[B](f: A => B): List[B] = { def loop(l: List[A], res: List[B]): List[B] = l match { case Nil => res case head :: tail => loop(tail, f(head) :: res) } loop(this, Nil) } /** Apply the given function f to each element of this list * (while respecting the order of the elements). * * @param f the treatment to apply to each element. */ final override def foreach(f: A => Unit) { var these = this while (!these.isEmpty) { f(these.head) these = these.tail } } /** Returns all the elements of this list that satisfy the * predicate p. The order of the elements is preserved. * It is guarenteed that the receiver list itself is returned iff all its * elements satisfy the predicate `p'. Hence the following equality is valid: * * (xs filter p) eq xs == xs forall p * * @param p the predicate used to filter the list. * @return the elements of this list satisfying p. */ final override def filter(p: A => Boolean): List[A] = { // return same list if all elements satisfy p var these = this while (!these.isEmpty && p(these.head)) { these = these.tail } if (these.isEmpty) this else { val b = new ListBuffer[A] var these1 = this while (these1 ne these) { b += these1.head these1 = these1.tail } these = these.tail // prevent the second evaluation of the predicate // on the element on which it first failed while (!these.isEmpty) { if (p(these.head)) b += these.head these = these.tail } b.toList } } // final def filterMap[B](f: PartialFunction[A, B]): List[B] = // this filter f.isDefinedAt map f /** Removes all elements of the list which satisfy the predicate * p. This is like filter with the * predicate inversed. * * @param p the predicate to use to test elements * @return the list without all elements which satisfy p */ def remove(p: A => Boolean): List[A] = filter (x => !p(x)) /** Partition the list in two sub-lists according to a predicate. * * @param p the predicate on which to partition * @return a pair of lists: the list of all elements which satisfy * p and the list of all elements which do not. * The relative order of the elements in the sub-lists is the * same as in the original list. */ def partition(p: A => Boolean): (List[A], List[A]) = { val btrue = new ListBuffer[A] val bfalse = new ListBuffer[A] var these = this while (!these.isEmpty) { (if (p(these.head)) btrue else bfalse) += these.head these = these.tail } (btrue.toList, bfalse.toList) } /**

* Sort the list according to the comparison function * <(e1: a, e2: a) => Boolean, * which should be true iff e1 is smaller than * e2. *

* * @param lt the comparison function * @return a list sorted according to the comparison function * <(e1: a, e2: a) => Boolean. * @ex
   *    List("Steve", "Tom", "John", "Bob")
   *      .sort((e1, e2) => (e1 compareTo e2) < 0) =
   *    List("Bob", "John", "Steve", "Tom")
*/ def sort(lt : (A,A) => Boolean): List[A] = { /** Merge two already-sorted lists */ def merge(l1: List[A], l2: List[A]): List[A] = { val res = new ListBuffer[A] var left1 = l1 var left2 = l2 while (!left1.isEmpty && !left2.isEmpty) { if(lt(left1.head, left2.head)) { res += left1.head left1 = left1.tail } else { res += left2.head left2 = left2.tail } } res ++= left1 res ++= left2 res.toList } /** Split a list into two lists of about the same size */ def split(lst: List[A]) = { val res1 = new ListBuffer[A] val res2 = new ListBuffer[A] var left = lst while (!left.isEmpty) { res1 += left.head left = left.tail if (!left.isEmpty) { res2 += left.head left = left.tail } } (res1.toList, res2.toList) } /** Merge-sort the specified list */ def ms(lst: List[A]): List[A] = lst match { case Nil => lst case x :: Nil => lst case x :: y :: Nil => if (lt(x,y)) lst else y :: x :: Nil case lst => val (l1, l2) = split(lst) val l1s = ms(l1) val l2s = ms(l2) merge(l1s, l2s) } ms(this) } /** Count the number of elements in the list which satisfy a predicate. * * @param p the predicate for which to count * @return the number of elements satisfying the predicate p. */ def count(p: A => Boolean): Int = { var cnt = 0 var these = this while (!these.isEmpty) { if (p(these.head)) cnt += 1 these = these.tail } cnt } /** Tests if the predicate p is satisfied by all elements * in this list. * * @param p the test predicate. * @return true iff all elements of this list satisfy the * predicate p. */ override def forall(p: A => Boolean): Boolean = { var these = this while (!these.isEmpty) { if (!p(these.head)) return false these = these.tail } true } /** Tests the existence in this list of an element that satisfies the * predicate p. * * @param p the test predicate. * @return true iff there exists an element in this list that * satisfies the predicate p. */ override def exists(p: A => Boolean): Boolean = { var these = this while (!these.isEmpty) { if (p(these.head)) return true these = these.tail } false } /** Find and return the first element of the list satisfying a * predicate, if any. * * @param p the predicate * @return the first element in the list satisfying p, * or None if none exists. */ override def find(p: A => Boolean): Option[A] = { var these = this while (!these.isEmpty) { if (p(these.head)) return Some(these.head) these = these.tail } None } /** Combines the elements of this list together using the binary * function f, from left to right, and starting with * the value z. * * @return f(... (f(f(z, a0), a1) ...), * an) if the list is * [a0, a1, ..., an]. */ override def foldLeft[B](z: B)(f: (B, A) => B): B = { var acc = z var these = this while (!these.isEmpty) { acc = f(acc, these.head) these = these.tail } acc } /** Combines the elements of this list together using the binary * function f, from right to left, and starting with * the value z. * * @return f(a0, f(a1, f(..., f(an, z)...))) * if the list is [a0, a1, ..., an]. */ override def foldRight[B](z: B)(f: (A, B) => B): B = this match { case Nil => z case x :: xs => f(x, xs.foldRight(z)(f)) } /** Combines the elements of this list together using the binary * operator op, from left to right * @param op The operator to apply * @return op(... op(a0,a1), ..., an) if the list has elements * a0, a1, ..., an. * @throws Predef.UnsupportedOperationException if the list is empty. */ override def reduceLeft[B >: A](f: (B, B) => B): B = this match { case Nil => throw new UnsupportedOperationException("Nil.reduceLeft") case x :: xs => ((xs: List[B]) foldLeft (x: B))(f) } /** Combines the elements of this list together using the binary * operator op, from right to left * @param op The operator to apply * * @return a0 op (... op (an-1 op an)...) * if the list has elements a0, a1, ..., * an. * * @throws Predef.UnsupportedOperationException if the list is empty. */ override def reduceRight[B >: A](f: (B, B) => B): B = this match { case Nil => throw new UnsupportedOperationException("Nil.reduceRight") case x :: Nil => x: B case x :: xs => f(x, xs reduceRight f) } /** Applies the given function f to each element of * this list, then concatenates the results. * * @param f the function to apply on each element. * @return f(a0) ::: ... ::: f(an) if * this list is [a0, ..., an]. */ final override def flatMap[B](f: A => Iterable[B]): List[B] = { val b = new ListBuffer[B] var these = this while (!these.isEmpty) { var those = f(these.head).elements while (those.hasNext) { b += those.next } these = these.tail } b.toList } /** A list consisting of all elements of this list in reverse order. */ override def reverse: List[A] = { var result: List[A] = Nil var these = this while (!these.isEmpty) { result = these.head :: result these = these.tail } result } /** Returns a list formed from this list and the specified list * that by associating each element of the former with * the element at the same position in the latter. * If one of the two lists is longer than the other, its remaining elements are ignored. * * @return List((a0,b0), ..., * (amin(m,n),bmin(m,n))) when * List(a0, ..., am) * zip List(b0, ..., bn) is invoked. */ def zip[B](that: List[B]): List[(A, B)] = { val b = new ListBuffer[(A, B)] var these = this var those = that while (!these.isEmpty && !those.isEmpty) { b += (these.head, those.head) these = these.tail those = those.tail } b.toList } /** Returns a list that pairs each element of this list * with its index, counting from 0. * * @return the list List((a0,0), (a1,1), ...) * where ai are the elements of this list. */ def zipWithIndex: List[(A, Int)] = { val b = new ListBuffer[(A, Int)] var these = this var idx = 0 while(!these.isEmpty) { b += (these.head, idx) these = these.tail idx += 1 } b.toList } /** Returns a list formed from this list and the specified list * that by associating each element of the former with * the element at the same position in the latter. * * @param that list that may have a different length * as the self list. * @param thisElem element thisElem is used to fill up the * resulting list if the self list is shorter than * that * @param thatElem element thatElem is used to fill up the * resulting list if that is shorter than * the self list * @return List((a0,b0), ..., * (an,bn), (elem,bn+1), * ..., {elem,bm}) * when [a0, ..., an] zip * [b0, ..., bm] is * invoked where m > n. */ def zipAll[B, C >: A, D >: B](that: List[B], thisElem: C, thatElem: D): List[(C, D)] = { val b = new ListBuffer[(C, D)] var these = this var those = that while (!these.isEmpty && !those.isEmpty) { b += (these.head, those.head) these = these.tail those = those.tail } while (!these.isEmpty) { b += (these.head, thatElem) these = these.tail } while (!those.isEmpty) { b += (thisElem, those.head) those = those.tail } b.toList } /** Computes the union of this list and the given list * that. * * @param that the list of elements to add to the list. * @return a list without doubles containing the elements of this * list and those of the given list that. */ def union[B >: A](that: List[B]): List[B] = { val b = new ListBuffer[B] var these = this while (!these.isEmpty) { if (!that.contains(these.head)) b += these.head these = these.tail } b.prependToList(that) } /** Computes the difference between this list and the given list * that. * * @param that the list of elements to remove from this list. * @return this list without the elements of the given list * that. */ def diff[B >: A](that: List[B]): List[B] = { val b = new ListBuffer[B] var these = this while (!these.isEmpty) { if (!that.contains(these.head)) b += these.head these = these.tail } b.toList } def flatten[B](implicit f : A => Iterable[B]) : List[B] = { val buf = new ListBuffer[B] foreach(f(_).foreach(buf += _)) buf.toList } /** Computes the intersection between this list and the given list * that. * * @param that the list to intersect. * @return the list of elements contained both in this list and * in the given list that. */ def intersect[B >: A](that: List[B]): List[B] = filter(x => that contains x) /** Removes redundant elements from the list. Uses the method == * to decide if two elements are identical. * * @return the list without doubles. */ def removeDuplicates: List[A] = { val b = new ListBuffer[A] var these = this while (!these.isEmpty) { if (!these.tail.contains(these.head)) b += these.head these = these.tail } b.toList } override protected def stringPrefix = "List" override def projection = toStream override def toStream : Stream[A] = new Stream.Definite[A] { override def force : List[A] = List.this override def isEmpty = List.this.isEmpty override def head = List.this.head override def tail = List.this.tail.toStream protected def addDefinedElems(buf: StringBuilder, prefix: String): StringBuilder = if (!isEmpty) { var prefix0 = prefix var buf1 = buf.append(prefix0).append(head) prefix0 = ", " var tail0 = tail while (!tail0.isEmpty) { buf1 = buf.append(prefix0).append(tail0.head) tail0 = tail0.tail } buf1 } else buf } } /** The empty list. * * @author Martin Odersky * @version 1.0, 15/07/2003 */ @SerialVersionUID(0 - 8256821097970055419L) case object Nil extends List[Nothing] { override def isEmpty = true def head: Nothing = throw new NoSuchElementException("head of empty list") def tail: List[Nothing] = throw new NoSuchElementException("tail of empty list") } /** A non empty list characterized by a head and a tail. * * @author Martin Odersky * @version 1.0, 15/07/2003 */ @SerialVersionUID(0L - 8476791151983527571L) final case class ::[B](hd: B, private[scala] var tl: List[B]) extends List[B] { def head = hd def tail = tl override def isEmpty: Boolean = false }