PageRenderTime 45ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/library/scala/collection/immutable/List.scala

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