1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
package scalax.collection
import generic._
import collection.immutable.{List, Nil, ::}
/** Collection classes mixing in this class provide a method
* <code>elements</code> which returns an iterator over all the
* elements contained in the collection.
*
* @note If a collection has a known <code>size</code>, it should also sub-type <code>SizedIterable</code>.
*
* @author Matthias Zenger
* @autor Martin Odersky
* @owner Martin Odersky
* @version 2.8
*/
trait Iterable[+A] extends covariant.IterableTemplate[Iterable, A] { self =>
/** Creates a view of this iterable @see Iterable.View
def view: View[Iterable, A] = new View[Iterable, A] { // !!! Martin: We should maybe infer the type parameters here?
val origin: self.type = self
val elements: Iterator[A] = self.elements
}
*/
}
/** Various utilities for instances of <a href="Iterable.html">Iterable</a>.
*
* @author Matthias Zenger
* @author Martin Odersky
* @version 2.8
*/
object Iterable extends covariant.IterableFactory[Iterable] {
/** The empty iterable */
val empty: Iterable[Nothing] = Nil
class ComparableIterableOps[A](seq: Iterable[A], cmp: Ordering[A]) {
def min: A = {
require(!seq.isEmpty, "min(<empty>)")
var acc = seq.elements.next
for (x <- seq)
if (cmp.lt(x, acc)) acc = x
acc
}
def max: A = {
require(!seq.isEmpty, "max(<empty>)")
var acc = seq.elements.next
for (x <- seq)
if (cmp.gt(x, acc)) acc = x
acc
}
}
class NumericIterableOps[A](seq: Iterable[A], num: Numeric[A]) {
def sum: A = {
var acc = num.zero
for (x <- seq) acc = num.plus(acc, x)
acc
}
def product: A = {
var acc = num.one
for (x <- seq) acc = num.times(acc, x)
acc
}
}
class IterableIterableOps[C[+B] <: Iterable[B] with covariant.IterableTemplate[C, B], A](self: C[C[A]]) {
def flatten: C[A] = {
val b: Builder[C, A] = self.newBuilder[A]
for (xs <- self)
b ++= xs
b.result
}
def transpose: C[C[A]] = {
val bs: Array[Builder[C, A]] = self.head.map(_ => self.newBuilder[A]).toArray
for (xs <- self) {
var i = 0
for (x <- xs) {
bs(i) += x
i += 1
}
}
type CC[B] = C[C[B]]
val bb = self.newBuilder[C[A]]
for (b <- bs) bb += b.result
bb.result
}
}
class PairIterableOps[C[+B] <: Iterable[B], A1, A2](self: C[(A1, A2)]) {
def unzip: (C[A1], C[A2]) = {
val as = self.newBuilder[A1].asInstanceOf[Builder[C, A1]]
val bs = self.newBuilder[A2].asInstanceOf[Builder[C, A2]]
for ((a, b) <- self) {
as += a
bs += b
}
(as.result, bs.result)
}
}
implicit def comparableIterableWrapper[A](seq: Iterable[A])(implicit cmp: Ordering[A]) =
new ComparableIterableOps(seq, cmp)
implicit def numericIterableWrapper[A](seq: Iterable[A])(implicit num: Numeric[A]) =
new NumericIterableOps(seq, num)
implicit def iterableIterableWrapper[C[+B] <: Iterable[B] with covariant.IterableTemplate[C, B], A](seq: C[C[A]]) =
new IterableIterableOps[C, A](seq)
implicit def pairIterableWrapper[C[+B] <: Iterable[B], A1, A2](seq: C[(A1, A2)]) =
new PairIterableOps[C, A1, A2](seq)
type View[+UC[B] <: Sequence[B], A] = IterableView[UC, A]
/** @deprecated use View instead
*/
@deprecated type Projection[A] = View[C, A] forSome { type C[B] <: Iterable[B] }
/** The minimum element of a non-empty sequence of ordered elements
* @deprecated use seq.min instead
*/
@deprecated def min[A <% Ordered[A]](seq: Iterable[A]): A = {
val xs = seq.elements
if (!xs.hasNext) throw new IllegalArgumentException("min(<empty>)")
var min = xs.next
while (xs.hasNext) {
val x = xs.next
if (x < min) min = x
}
min
}
/** The maximum element of a non-empty sequence of ordered elements
* @deprecated use seq.max iConstead
*/
@deprecated def max[A <% Ordered[A]](seq: Iterable[A]): A = {
val xs = seq.elements
if (!xs.hasNext) throw new IllegalArgumentException("max(<empty>)")
var max = xs.next
while (xs.hasNext) {
val x = xs.next
if (max < x) max = x
}
max
}
}
|