PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/scalalib/scala/collection/immutable/List.scala

http://github.com/sjrd/ozma
Scala | 810 lines | 491 code | 84 blank | 235 comment | 96 complexity | a4ed60196614f1cba579f4e763a6050a MD5 | raw file
  1. /* __ *\
  2. ** ________ ___ / / ___ Scala API **
  3. ** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
  4. ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
  5. ** /____/\___/_/ |_/____/_/ | | **
  6. ** |/ **
  7. \* */
  8. package scala.collection
  9. package immutable
  10. import generic._
  11. import mutable.{Builder, ListBuffer}
  12. import annotation.tailrec
  13. import scala.ozma.tailcall
  14. /** A class for immutable linked lists representing ordered collections
  15. * of elements of type.
  16. *
  17. * This class comes with two implementing case classes `scala.Nil`
  18. * and `scala.::` that implement the abstract members `isEmpty`,
  19. * `head` and `tail`.
  20. *
  21. * @author Martin Odersky and others
  22. * @version 2.8
  23. * @since 1.0
  24. *
  25. * @tparam A the type of the list's elements
  26. *
  27. * @define Coll List
  28. * @define coll list
  29. * @define thatinfo the class of the returned collection. In the standard library configuration,
  30. * `That` is always `List[B]` because an implicit of type `CanBuildFrom[List, B, That]`
  31. * is defined in object `List`.
  32. * @define bfinfo an implicit value of class `CanBuildFrom` which determines the
  33. * result class `That` from the current representation type `Repr`
  34. * and the new element type `B`. This is usually the `canBuildFrom` value
  35. * defined in object `List`.
  36. * @define orderDependent
  37. * @define orderDependentFold
  38. * @define mayNotTerminateInf
  39. * @define willNotTerminateInf
  40. */
  41. sealed abstract class List[+A] extends LinearSeq[A]
  42. with Product
  43. with GenericTraversableTemplate[A, List]
  44. with LinearSeqOptimized[A, List[A]] {
  45. override def companion: GenericCompanion[List] = List
  46. import scala.collection.{Iterable, Traversable, Seq, IndexedSeq}
  47. def isEmpty: Boolean
  48. def head: A
  49. def tail: List[A]
  50. // New methods in List
  51. /** Adds an element at the beginning of this list.
  52. * @param x the element to prepend.
  53. * @return a list which contains `x` as first element and
  54. * which continues with this list.
  55. * @example `1 :: List(2, 3) = List(2, 3).::(1) = List(1, 2, 3)`
  56. * @usecase def ::(x: A): List[A]
  57. */
  58. def ::[B >: A] (x: B): List[B] =
  59. new scala.collection.immutable.::(x, this)
  60. /** Adds the elements of a given list in front of this list.
  61. * @param prefix The list elements to prepend.
  62. * @return a list resulting from the concatenation of the given
  63. * list `prefix` and this list.
  64. * @example `List(1, 2) ::: List(3, 4) = List(3, 4).:::(List(1, 2)) = List(1, 2, 3, 4)`
  65. * @usecase def :::(prefix: List[A]): List[A]
  66. */
  67. def :::[B >: A](prefix: List[B]): List[B] =
  68. if (prefix.isEmpty) this
  69. else prefix.head :: (prefix.tail ::: this)
  70. /** Adds the elements of a given list in reverse order in front of this list.
  71. * `xs reverse_::: ys` is equivalent to
  72. * `xs.reverse ::: ys` but is more efficient.
  73. *
  74. * @param prefix the prefix to reverse and then prepend
  75. * @return the concatenation of the reversed prefix and the current list.
  76. * @usecase def reverse_:::(prefix: List[A]): List[A]
  77. */
  78. def reverse_:::[B >: A](prefix: List[B]): List[B] = {
  79. var these: List[B] = this
  80. var pres = prefix
  81. while (!pres.isEmpty) {
  82. these = pres.head :: these
  83. pres = pres.tail
  84. }
  85. these
  86. }
  87. /** Builds a new list by applying a function to all elements of this list.
  88. * Like `xs map f`, but returns `xs` unchanged if function
  89. * `f` maps all elements to themselves (wrt eq).
  90. *
  91. * @param f the function to apply to each element.
  92. * @tparam B the element type of the returned collection.
  93. * @return a list resulting from applying the given function
  94. * `f` to each element of this list and collecting the results.
  95. * @usecase def mapConserve(f: A => A): List[A]
  96. */
  97. def mapConserve[B >: A <: AnyRef](f: A => B): List[B] = {
  98. @tailrec
  99. def loop(mapped: ListBuffer[B], unchanged: List[A], pending: List[A]): List[B] =
  100. if (pending.isEmpty) {
  101. if (mapped eq null) unchanged
  102. else mapped.prependToList(unchanged)
  103. }
  104. else {
  105. val head0 = pending.head
  106. val head1 = f(head0)
  107. if (head1 eq head0.asInstanceOf[AnyRef])
  108. loop(mapped, unchanged, pending.tail)
  109. else {
  110. val b = if (mapped eq null) new ListBuffer[B] else mapped
  111. var xc = unchanged
  112. while (xc ne pending) {
  113. b += xc.head
  114. xc = xc.tail
  115. }
  116. b += head1
  117. val tail0 = pending.tail
  118. loop(b, tail0, tail0)
  119. }
  120. }
  121. loop(null, this, this)
  122. }
  123. // Overridden methods from IterableLike and SeqLike or overloaded variants of such methods
  124. override def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {
  125. val b = bf(this)
  126. if (b.isInstanceOf[ListBuffer[_]]) (this ::: that.seq.toList).asInstanceOf[That]
  127. else super.++(that)
  128. }
  129. override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That = bf match {
  130. case _: List.GenericCanBuildFrom[_] => (elem :: this).asInstanceOf[That]
  131. case _ => super.+:(elem)(bf)
  132. }
  133. override def toList: List[A] = this
  134. override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = {
  135. val b = bf(repr)
  136. if (b.isInstanceOf[ListBuffer[_]])
  137. mapList(f).asInstanceOf[That]
  138. else {
  139. b.sizeHint(this)
  140. for (x <- this) b += f(x)
  141. b.result
  142. }
  143. }
  144. private def mapList[B](f: A => B): List[B] = {
  145. if (isEmpty)
  146. Nil
  147. else
  148. f(head) :: tail.mapList(f)
  149. }
  150. override def filter(p: A => Boolean): List[A] = {
  151. if (isEmpty)
  152. Nil
  153. else if (p(head))
  154. head :: tail.filter(p)
  155. else
  156. tail.filter(p)
  157. }
  158. override def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[List[A], B, That]): That = {
  159. val b = bf(repr)
  160. if (b.isInstanceOf[ListBuffer[_]])
  161. collectList(pf).asInstanceOf[That]
  162. else {
  163. for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
  164. b.result
  165. }
  166. }
  167. private def collectList[B](pf: PartialFunction[A, B]): List[B] = {
  168. if (isEmpty)
  169. Nil
  170. else if (pf.isDefinedAt(head))
  171. pf(head) :: tail.collectList(pf)
  172. else
  173. tail.collectList(pf)
  174. }
  175. override def take(n: Int): List[A] = {
  176. if (n == 0 || isEmpty)
  177. Nil
  178. else
  179. head :: tail.take(n-1)
  180. }
  181. override def drop(n: Int): List[A] = {
  182. if (n == 0 || isEmpty)
  183. this
  184. else
  185. tail.drop(n-1)
  186. }
  187. override def slice(from: Int, until: Int): List[A] = {
  188. val lo = math.max(from, 0)
  189. if (until <= lo || isEmpty) Nil
  190. else this drop lo take (until - lo)
  191. }
  192. override def takeRight(n: Int): List[A] = {
  193. @tailrec
  194. def loop(lead: List[A], lag: List[A]): List[A] = lead match {
  195. case Nil => lag
  196. case _ :: tail => loop(tail, lag.tail)
  197. }
  198. loop(drop(n), this)
  199. }
  200. // dropRight is inherited from LinearSeq
  201. override def splitAt(n: Int): (List[A], List[A]) = {
  202. val b = new ListBuffer[A]
  203. var i = 0
  204. var these = this
  205. while (!these.isEmpty && i < n) {
  206. i += 1
  207. b += these.head
  208. these = these.tail
  209. }
  210. (b.toList, these)
  211. }
  212. override def takeWhile(p: A => Boolean): List[A] = {
  213. if (isEmpty || !p(head))
  214. Nil
  215. else
  216. head :: tail.takeWhile(p)
  217. }
  218. override def dropWhile(p: A => Boolean): List[A] = {
  219. if (isEmpty || p(head))
  220. this
  221. else
  222. tail.dropWhile(p)
  223. }
  224. override def span(p: A => Boolean): (List[A], List[A]) = {
  225. val b = new ListBuffer[A]
  226. var these = this
  227. while (!these.isEmpty && p(these.head)) {
  228. b += these.head
  229. these = these.tail
  230. }
  231. (b.toList, these)
  232. }
  233. override def reverse: List[A] = {
  234. def loop(list: List[A], acc: List[A]): List[A] = {
  235. if (list.isEmpty)
  236. acc
  237. else
  238. loop(list.tail, list.head :: acc)
  239. }
  240. loop(this, Nil)
  241. }
  242. override def stringPrefix = "List"
  243. override def toStream : Stream[A] =
  244. if (isEmpty) Stream.Empty
  245. else new Stream.Cons(head, tail.toStream)
  246. /** Like <code>span</code> but with the predicate inverted.
  247. */
  248. @deprecated("use `span { x => !p(x) }` instead", "2.8.0")
  249. def break(p: A => Boolean): (List[A], List[A]) = span { x => !p(x) }
  250. @deprecated("use `filterNot' instead", "2.8.0")
  251. def remove(p: A => Boolean): List[A] = filterNot(p)
  252. /** Computes the difference between this list and the given list
  253. * `that`.
  254. *
  255. * @param that the list of elements to remove from this list.
  256. * @return this list without the elements of the given list
  257. * `that`.
  258. */
  259. @deprecated("use `list1 filterNot (list2 contains)` instead", "2.8.0")
  260. def -- [B >: A](that: List[B]): List[B] = {
  261. val b = new ListBuffer[B]
  262. var these = this
  263. while (!these.isEmpty) {
  264. if (!that.contains(these.head)) b += these.head
  265. these = these.tail
  266. }
  267. b.toList
  268. }
  269. /** Computes the difference between this list and the given object
  270. * `x`.
  271. *
  272. * @param x the object to remove from this list.
  273. * @return this list without occurrences of the given object
  274. * `x`.
  275. */
  276. @deprecated("use `filterNot (_ == x)` instead", "2.8.0")
  277. def - [B >: A](x: B): List[B] = {
  278. val b = new ListBuffer[B]
  279. var these = this
  280. while (!these.isEmpty) {
  281. if (these.head != x) b += these.head
  282. these = these.tail
  283. }
  284. b.toList
  285. }
  286. @deprecated("use `distinct' instead", "2.8.0")
  287. def removeDuplicates: List[A] = distinct
  288. @deprecated("use `sortWith' instead", "2.8.0")
  289. def sort(lt : (A,A) => Boolean): List[A] = {
  290. /** Merge two already-sorted lists */
  291. def merge(l1: List[A], l2: List[A]): List[A] = {
  292. val res = new ListBuffer[A]
  293. var left1 = l1
  294. var left2 = l2
  295. while (!left1.isEmpty && !left2.isEmpty) {
  296. if(lt(left1.head, left2.head)) {
  297. res += left1.head
  298. left1 = left1.tail
  299. } else {
  300. res += left2.head
  301. left2 = left2.tail
  302. }
  303. }
  304. res ++= left1
  305. res ++= left2
  306. res.toList
  307. }
  308. /** Split a list into two lists of about the same size */
  309. def split(lst: List[A]) = {
  310. val res1 = new ListBuffer[A]
  311. val res2 = new ListBuffer[A]
  312. var left = lst
  313. while (!left.isEmpty) {
  314. res1 += left.head
  315. left = left.tail
  316. if (!left.isEmpty) {
  317. res2 += left.head
  318. left = left.tail
  319. }
  320. }
  321. (res1.toList, res2.toList)
  322. }
  323. /** Merge-sort the specified list */
  324. def ms(lst: List[A]): List[A] =
  325. lst match {
  326. case Nil => lst
  327. case x :: Nil => lst
  328. case x :: y :: Nil =>
  329. if (lt(x,y))
  330. lst
  331. else
  332. y :: x :: Nil
  333. case lst =>
  334. val (l1, l2) = split(lst)
  335. val l1s = ms(l1)
  336. val l2s = ms(l2)
  337. merge(l1s, l2s)
  338. }
  339. ms(this)
  340. }
  341. }
  342. /** The empty list.
  343. *
  344. * @author Martin Odersky
  345. * @version 1.0, 15/07/2003
  346. * @since 2.8
  347. */
  348. @SerialVersionUID(0 - 8256821097970055419L)
  349. case object Nil extends List[Nothing] {
  350. override def isEmpty = true
  351. override def head: Nothing =
  352. throw new NoSuchElementException("head of empty list")
  353. override def tail: List[Nothing] =
  354. throw new UnsupportedOperationException("tail of empty list")
  355. // Removal of equals method here might lead to an infinite recursion similar to IntMap.equals.
  356. override def equals(that: Any) = that match {
  357. case that1: collection.Seq[_] => that1.isEmpty
  358. case _ => false
  359. }
  360. }
  361. /** A non empty list characterized by a head and a tail.
  362. * @param hd the first element of the list
  363. * @param tl the list containing the remaining elements of this list after the first one.
  364. * @tparam B the type of the list elements.
  365. * @author Martin Odersky
  366. * @version 1.0, 15/07/2003
  367. * @since 2.8
  368. */
  369. @SerialVersionUID(0L - 8476791151983527571L)
  370. final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] {
  371. override def head : B = hd
  372. override def tail : List[B] = tl
  373. override def isEmpty: Boolean = false
  374. import java.io._
  375. private def writeObject(out: ObjectOutputStream) {
  376. var xs: List[B] = this
  377. while (!xs.isEmpty) { out.writeObject(xs.head); xs = xs.tail }
  378. out.writeObject(ListSerializeEnd)
  379. }
  380. private def readObject(in: ObjectInputStream) {
  381. hd = in.readObject.asInstanceOf[B]
  382. assert(hd != ListSerializeEnd)
  383. var current: ::[B] = this
  384. while (true) in.readObject match {
  385. case ListSerializeEnd =>
  386. current.tl = Nil
  387. return
  388. case a : Any =>
  389. val list : ::[B] = new ::(a.asInstanceOf[B], Nil)
  390. current.tl = list
  391. current = list
  392. }
  393. }
  394. }
  395. /** $factoryInfo
  396. * @define coll list
  397. * @define Coll List
  398. */
  399. object List extends SeqFactory[List] {
  400. import scala.collection.{Iterable, Seq, IndexedSeq}
  401. /** $genericCanBuildFromInfo */
  402. implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] = new GenericCanBuildFrom[A]
  403. def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A]
  404. override def empty[A]: List[A] = Nil
  405. override def apply[A](xs: A*): List[A] = xs.toList
  406. /** Create a sorted list with element values
  407. * `v<sub>n+1</sub> = step(v<sub>n</sub>)`
  408. * where `v<sub>0</sub> = start`
  409. * and elements are in the range between `start` (inclusive)
  410. * and `end` (exclusive)
  411. *
  412. * @param start the start value of the list
  413. * @param end the end value of the list
  414. * @param step the increment function of the list, which given `v<sub>n</sub>`,
  415. * computes `v<sub>n+1</sub>`. Must be monotonically increasing
  416. * or decreasing.
  417. * @return the sorted list of all integers in range [start;end).
  418. */
  419. @deprecated("use `iterate' instead", "2.8.0")
  420. def range(start: Int, end: Int, step: Int => Int): List[Int] = {
  421. val up = step(start) > start
  422. val down = step(start) < start
  423. val b = new ListBuffer[Int]
  424. var i = start
  425. while ((!up || i < end) && (!down || i > end)) {
  426. b += i
  427. val next = step(i)
  428. if (i == next)
  429. throw new IllegalArgumentException("the step function did not make any progress on "+ i)
  430. i = next
  431. }
  432. b.toList
  433. }
  434. /** Create a list containing several copies of an element.
  435. *
  436. * @param n the length of the resulting list
  437. * @param elem the element composing the resulting list
  438. * @return a list composed of n elements all equal to elem
  439. */
  440. @deprecated("use `fill' instead", "2.8.0")
  441. def make[A](n: Int, elem: A): List[A] = {
  442. val b = new ListBuffer[A]
  443. var i = 0
  444. while (i < n) {
  445. b += elem
  446. i += 1
  447. }
  448. b.toList
  449. }
  450. /** Concatenate all the elements of a given list of lists.
  451. *
  452. * @param xss the list of lists that are to be concatenated
  453. * @return the concatenation of all the lists
  454. */
  455. @deprecated("use `xss.flatten' instead of `List.flatten(xss)'", "2.8.0")
  456. def flatten[A](xss: List[List[A]]): List[A] = {
  457. val b = new ListBuffer[A]
  458. for (xs <- xss) {
  459. var xc = xs
  460. while (!xc.isEmpty) {
  461. b += xc.head
  462. xc = xc.tail
  463. }
  464. }
  465. b.toList
  466. }
  467. /** Transforms a list of pairs into a pair of lists.
  468. *
  469. * @param xs the list of pairs to unzip
  470. * @return a pair of lists.
  471. */
  472. @deprecated("use `xs.unzip' instead of `List.unzip(xs)'", "2.8.0")
  473. def unzip[A,B](xs: List[(A,B)]): (List[A], List[B]) = {
  474. val b1 = new ListBuffer[A]
  475. val b2 = new ListBuffer[B]
  476. var xc = xs
  477. while (!xc.isEmpty) {
  478. b1 += xc.head._1
  479. b2 += xc.head._2
  480. xc = xc.tail
  481. }
  482. (b1.toList, b2.toList)
  483. }
  484. /** Transforms an iterable of pairs into a pair of lists.
  485. *
  486. * @param xs the iterable of pairs to unzip
  487. * @return a pair of lists.
  488. */
  489. @deprecated("use `xs.unzip' instead of `List.unzip(xs)'", "2.8.0")
  490. def unzip[A,B](xs: Iterable[(A,B)]): (List[A], List[B]) =
  491. xs.foldRight[(List[A], List[B])]((Nil, Nil)) {
  492. case ((x, y), (xs, ys)) => (x :: xs, y :: ys)
  493. }
  494. /**
  495. * Returns the `Left` values in the given `Iterable`
  496. * of `Either`s.
  497. */
  498. @deprecated("use `xs collect { case Left(x: A) => x }' instead of `List.lefts(xs)'", "2.8.0")
  499. def lefts[A, B](es: Iterable[Either[A, B]]) =
  500. es.foldRight[List[A]](Nil)((e, as) => e match {
  501. case Left(a) => a :: as
  502. case Right(_) => as
  503. })
  504. /**
  505. * Returns the `Right` values in the given`Iterable` of `Either`s.
  506. */
  507. @deprecated("use `xs collect { case Right(x: B) => x }' instead of `List.rights(xs)'", "2.8.0")
  508. def rights[A, B](es: Iterable[Either[A, B]]) =
  509. es.foldRight[List[B]](Nil)((e, bs) => e match {
  510. case Left(_) => bs
  511. case Right(b) => b :: bs
  512. })
  513. /** Transforms an Iterable of Eithers into a pair of lists.
  514. *
  515. * @param xs the iterable of Eithers to separate
  516. * @return a pair of lists.
  517. */
  518. @deprecated("use `(for (Left(x) <- es) yield x, for (Right(x) <- es) yield x)` instead", "2.8.0")
  519. def separate[A,B](es: Iterable[Either[A, B]]): (List[A], List[B]) =
  520. es.foldRight[(List[A], List[B])]((Nil, Nil)) {
  521. case (Left(a), (lefts, rights)) => (a :: lefts, rights)
  522. case (Right(b), (lefts, rights)) => (lefts, b :: rights)
  523. }
  524. /** Converts an iterator to a list.
  525. *
  526. * @param it the iterator to convert
  527. * @return a list that contains the elements returned by successive
  528. * calls to `it.next`
  529. */
  530. @deprecated("use `it.toList' instead of `List.toList(it)'", "2.8.0")
  531. def fromIterator[A](it: Iterator[A]): List[A] = it.toList
  532. /** Converts an array into a list.
  533. *
  534. * @param arr the array to convert
  535. * @return a list that contains the same elements than `arr`
  536. * in the same order
  537. */
  538. @deprecated("use `array.toList' instead of `List.fromArray(array)'", "2.8.0")
  539. def fromArray[A](arr: Array[A]): List[A] = fromArray(arr, 0, arr.length)
  540. /** Converts a range of an array into a list.
  541. *
  542. * @param arr the array to convert
  543. * @param start the first index to consider
  544. * @param len the length of the range to convert
  545. * @return a list that contains the same elements than `arr`
  546. * in the same order
  547. */
  548. @deprecated("use `array.view(start, end).toList' instead of `List.fromArray(array, start, end)'", "2.8.0")
  549. def fromArray[A](arr: Array[A], start: Int, len: Int): List[A] = {
  550. var res: List[A] = Nil
  551. var i = start + len
  552. while (i > start) {
  553. i -= 1
  554. res = arr(i) :: res
  555. }
  556. res
  557. }
  558. /** Parses a string which contains substrings separated by a
  559. * separator character and returns a list of all substrings.
  560. *
  561. * @param str the string to parse
  562. * @param separator the separator character
  563. * @return the list of substrings
  564. */
  565. @deprecated("use `str.split(separator).toList' instead of `List.fromString(str, separator)'", "2.8.0")
  566. def fromString(str: String, separator: Char): List[String] = {
  567. var words: List[String] = Nil
  568. var pos = str.length()
  569. while (pos > 0) {
  570. val pos1 = str.lastIndexOf(separator, pos - 1)
  571. if (pos1 + 1 < pos)
  572. words = str.substring(pos1 + 1, pos) :: words
  573. pos = pos1
  574. }
  575. words
  576. }
  577. /** Returns the given list of characters as a string.
  578. *
  579. * @param xs the list to convert.
  580. * @return the list in form of a string.
  581. */
  582. @deprecated("use `xs.mkString' instead of `List.toString(xs)'", "2.8.0")
  583. def toString(xs: List[Char]): String = {
  584. val sb = new StringBuilder()
  585. var xc = xs
  586. while (!xc.isEmpty) {
  587. sb.append(xc.head)
  588. xc = xc.tail
  589. }
  590. sb.toString()
  591. }
  592. /** Like xs map f, but returns `xs` unchanged if function
  593. * `f` maps all elements to themselves.
  594. */
  595. @deprecated("use `xs.mapConserve(f)' instead of `List.mapConserve(xs, f)'", "2.8.0")
  596. def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A] = {
  597. def loop(ys: List[A]): List[A] =
  598. if (ys.isEmpty) xs
  599. else {
  600. val head0 = ys.head
  601. val head1 = f(head0)
  602. if (head1 eq head0) {
  603. loop(ys.tail)
  604. } else {
  605. val ys1 = head1 :: mapConserve(ys.tail)(f)
  606. if (xs eq ys) ys1
  607. else {
  608. val b = new ListBuffer[A]
  609. var xc = xs
  610. while (xc ne ys) {
  611. b += xc.head
  612. xc = xc.tail
  613. }
  614. b.prependToList(ys1)
  615. }
  616. }
  617. }
  618. loop(xs)
  619. }
  620. /** Returns the list resulting from applying the given function `f`
  621. * to corresponding elements of the argument lists.
  622. *
  623. * @param f function to apply to each pair of elements.
  624. * @return `[f(a0,b0), ..., f(an,bn)]` if the lists are
  625. * `[a0, ..., ak]`, `[b0, ..., bl]` and
  626. * `n = min(k,l)`
  627. */
  628. @deprecated("use `(xs, ys).zipped.map(f)' instead of `List.map2(xs, ys)(f)'", "2.8.0")
  629. def map2[A,B,C](xs: List[A], ys: List[B])(f: (A, B) => C): List[C] = {
  630. val b = new ListBuffer[C]
  631. var xc = xs
  632. var yc = ys
  633. while (!xc.isEmpty && !yc.isEmpty) {
  634. b += f(xc.head, yc.head)
  635. xc = xc.tail
  636. yc = yc.tail
  637. }
  638. b.toList
  639. }
  640. /** Returns the list resulting from applying the given function
  641. * `f` to corresponding elements of the argument lists.
  642. *
  643. * @param f function to apply to each pair of elements.
  644. * @return `[f(a<sub>0</sub>,b<sub>0</sub>,c<sub>0</sub>),
  645. * ..., f(a<sub>n</sub>,b<sub>n</sub>,c<sub>n</sub>)]`
  646. * if the lists are `[a<sub>0</sub>, ..., a<sub>k</sub>]`,
  647. * `[b<sub>0</sub>, ..., b<sub>l</sub>]`,
  648. * `[c<sub>0</sub>, ..., c<sub>m</sub>]` and
  649. * `n = min(k,l,m)`
  650. */
  651. @deprecated("use `(xs, ys, zs).zipped.map(f)' instead of `List.map3(xs, ys, zs)(f)'", "2.8.0")
  652. def map3[A,B,C,D](xs: List[A], ys: List[B], zs: List[C])(f: (A, B, C) => D): List[D] = {
  653. val b = new ListBuffer[D]
  654. var xc = xs
  655. var yc = ys
  656. var zc = zs
  657. while (!xc.isEmpty && !yc.isEmpty && !zc.isEmpty) {
  658. b += f(xc.head, yc.head, zc.head)
  659. xc = xc.tail
  660. yc = yc.tail
  661. zc = zc.tail
  662. }
  663. b.toList
  664. }
  665. /** Tests whether the given predicate `p` holds
  666. * for all corresponding elements of the argument lists.
  667. *
  668. * @param p function to apply to each pair of elements.
  669. * @return `(p(a<sub>0</sub>,b<sub>0</sub>) &amp;&amp;
  670. * ... &amp;&amp; p(a<sub>n</sub>,b<sub>n</sub>))]`
  671. * if the lists are `[a<sub>0</sub>, ..., a<sub>k</sub>]`;
  672. * `[b<sub>0</sub>, ..., b<sub>l</sub>]`
  673. * and `n = min(k,l)`
  674. */
  675. @deprecated("use `(xs, ys).zipped.forall(f)' instead of `List.forall2(xs, ys)(f)'", "2.8.0")
  676. def forall2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = {
  677. var xc = xs
  678. var yc = ys
  679. while (!xc.isEmpty && !yc.isEmpty) {
  680. if (!f(xc.head, yc.head)) return false
  681. xc = xc.tail
  682. yc = yc.tail
  683. }
  684. true
  685. }
  686. /** Tests whether the given predicate `p` holds
  687. * for some corresponding elements of the argument lists.
  688. *
  689. * @param p function to apply to each pair of elements.
  690. * @return `n != 0 &amp;&amp; (p(a<sub>0</sub>,b<sub>0</sub>) ||
  691. * ... || p(a<sub>n</sub>,b<sub>n</sub>))]` if the lists are
  692. * `[a<sub>0</sub>, ..., a<sub>k</sub>]`,
  693. * `[b<sub>0</sub>, ..., b<sub>l</sub>]` and
  694. * `n = min(k,l)`
  695. */
  696. @deprecated("use `(xs, ys).zipped.exists(f)' instead of `List.exists2(xs, ys)(f)'", "2.8.0")
  697. def exists2[A,B](xs: List[A], ys: List[B])(f: (A, B) => Boolean): Boolean = {
  698. var xc = xs
  699. var yc = ys
  700. while (!xc.isEmpty && !yc.isEmpty) {
  701. if (f(xc.head, yc.head)) return true
  702. xc = xc.tail
  703. yc = yc.tail
  704. }
  705. false
  706. }
  707. /** Transposes a list of lists.
  708. * pre: All element lists have the same length.
  709. *
  710. * @param xss the list of lists
  711. * @return the transposed list of lists
  712. */
  713. @deprecated("use `xss.transpose' instead of `List.transpose(xss)'", "2.8.0")
  714. def transpose[A](xss: List[List[A]]): List[List[A]] = {
  715. val buf = new ListBuffer[List[A]]
  716. var yss = xss
  717. while (!yss.head.isEmpty) {
  718. buf += (yss map (_.head))
  719. yss = (yss map (_.tail))
  720. }
  721. buf.toList
  722. }
  723. }
  724. /** Only used for list serialization */
  725. @SerialVersionUID(0L - 8476791151975527571L)
  726. private[scala] case object ListSerializeEnd