📄 list.scala
字号:
/* __ *\** ________ ___ / / ___ Scala API **** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **** /____/\___/_/ |_/____/_/ | | **** |/ **\* */// $Id: List.scala 14498 2008-04-04 12:12:27Z washburn $package scalaimport scala.collection.mutable.ListBufferimport 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 <code>n</code>, * returns the nth element of the resulting list, where * <code>n</code> is in interval <code>[0;n)</code>. * @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 <code>it.next</code> */ 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 <code>arr</code> * 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 <code>arr</code> * 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 <code>str.toList</code> 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 <code>xs</code> unchanged if function * <code>f</code> 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 <code>f</code> * to corresponding elements of the argument lists. * * @param f function to apply to each pair of elements. * @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are * <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and * <code>n = min(k,l)</code> */ 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 * <code>f</code> to corresponding elements of the argument lists. * * @param f function to apply to each pair of elements. * @return <code>[f(a<sub>0</sub>,b<sub>0</sub>,c<sub>0</sub>), * ..., f(a<sub>n</sub>,b<sub>n</sub>,c<sub>n</sub>)]</code> * if the lists are <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>, * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code>, * <code>[c<sub>0</sub>, ..., c<sub>m</sub>]</code> and * <code>n = min(k,l,m)</code> */ 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 <code>p</code> holds * for all corresponding elements of the argument lists. * * @param p function to apply to each pair of elements. * @return <code>(p(a<sub>0</sub>,b<sub>0</sub>) && * ... && p(a<sub>n</sub>,b<sub>n</sub>))]</code> * if the lists are <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>; * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code> * and <code>n = min(k,l)</code> */ 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 <code>p</code> holds * for some corresponding elements of the argument lists. * * @param p function to apply to each pair of elements. * @return <code>n != 0 && (p(a<sub>0</sub>,b<sub>0</sub>) || * ... || p(a<sub>n</sub>,b<sub>n</sub>))]</code> if the lists are * <code>[a<sub>0</sub>, ..., a<sub>k</sub>]</code>, * <code>[b<sub>0</sub>, ..., b<sub>l</sub>]</code> and * <code>n = min(k,l)</code> */ 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 * <code>a</code>. This class comes with two implementing case * classes <code>scala.Nil</code> and <code>scala.::</code> that * implement the abstract members <code>isEmpty</code>, * <code>head</code> and <code>tail</code>. * * @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 <code>true</code>, 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 length - l, without calling length */ override def lengthCompare(l: Int) = { if (isEmpty) 0 - l else if (l <= 0) 1 else tail.lengthCompare(l - 1) } /** Returns this list without its first element. * * @return this list without its first element. * @throws Predef.NoSuchElementException if the list is empty.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -