How to implement Scala equivalent to Java Iterable<T>
and C# IEnumerable<T>
? Basically, I want my collection to be mappable, filterable etc. What traits should the collection class extend and are there easy ways (something like yield return
and yield break
in C#) to create enumerator?
Asked
Active
Viewed 7,798 times
10

Mirco Widmer
- 2,139
- 1
- 20
- 44

synapse
- 5,588
- 6
- 35
- 65
3 Answers
14
Implement the Iterable
trait. All that is required is the iterator
method. All the other methods (map
, filter
, etc) come for free.
class MyIterable[T](xs: Vector[T]) extends Iterable[T] {
override def iterator = xs.iterator
}
val a = new MyIterable(Vector(1,2,3))
a.map(_+1) // res0: Iterable[Int] = List(2, 3, 4)
a.filter(_%2==1) // res1: Iterable[Int] = List(1, 3)

dhg
- 52,383
- 8
- 123
- 144
-
whatis the performance burden of that code? meaning: does it take O(n) time? – Stefan Kunze Oct 23 '13 at 23:10
-
@StefanKunze, *what* does take O(n) time? Of course, say, index lookup will be linear. But this is iterable, after all, not indexable. – Vladimir Matveev Oct 24 '13 at 06:00
-
the initial conversion to an iterator? – Stefan Kunze Oct 24 '13 at 14:41
-
"converting" to an iterator is constant, since it doesn't have to convert anything. All it has to do is wrap the vector and advance an index every time `next` is called. – dhg Oct 25 '13 at 16:02
-
This code does nothing but overriding the iterator. I don't see how is this useful. – Juan Pablo Gómez Uribe Sep 20 '21 at 18:55
0
You can use scala.collection.Iterable
trait or its immutable version which are pretty comprehensive and powerful. Hope that will help.

Laksitha Ranasingha
- 4,321
- 1
- 28
- 33
0
Regarding the enumerators, there is Enumeration in Scala but using sealed traits + derived classes seems to be more flexible, for example:
sealed trait MyEnum {
lazy val value = 0
}
case object MyEnumA extends MyEnum {
override lazy val value = 1
}
case object MyEnumB extends MyEnum {
override lazy val value = 2
}
scala> val a = MyEnumB
a: MyEnumB.type = MyEnumB
scala> a.value
res24: Int = 2
scala> val l = List(MyEnumA,MyEnumB)
l: List[Product with Serializable with MyEnum] = List(MyEnumA, MyEnumB)
scala> l.map(_.value)
res29: List[Int] = List(1, 2)
You can use these objects without any internal structure as well, if you don't care about mapping them to anything except their string representations:
sealed trait MyEnum
case object MyEnumA extends MyEnum
case object MyEnumB extends MyEnum
scala> val a = MyEnumA
a: MyEnumA.type = MyEnumA
scala> a.toString
res21: String = MyEnumA
scala> val l = List(MyEnumA,MyEnumB)
l: List[Product with Serializable with MyEnum] = List(MyEnumA, MyEnumB)
scala> l.map(_.toString)
res30: List[String] = List(MyEnumA, MyEnumB)

Ashalynd
- 12,363
- 2
- 34
- 37