Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala - Getting a read-only sublist view of a List

I would like a List, Seq, or even an Iterable that is a read-only view of a part of a List, in my specific case, the view will always start at the first element.

List.slice, is O(n) as is filter. Is there anyway of doing better than this - I don't need any operations like +, - etc. Just apply, map, flatMap, etc to provide for list comprehension syntax on the sub list.

Is the answer to write my own class whose iterators keep a count to know where the end is?

like image 516
daveb Avatar asked Dec 08 '22 06:12

daveb


2 Answers

How about Stream? Stream is Scala's way to laziness. Because of Stream's laziness, Stream.take(), which is what you need in this case, is O(1). The only caveat is that if you want to get back a List after doing a list comprehension on a Stream, you need to convert it back to a List. List.projection gets you a Stream which has most of the opeations of a List.

scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)

scala> val s = l.projection.take(3)
s: Stream[Int] = Stream(1, ?)

scala> s.map(_ * 2).toList
res0: List[Int] = List(2, 4, 6)

scala> (for (i <- s) yield i * 2).toList
res1: List[Int] = List(2, 4, 6)
like image 188
Walter Chang Avatar answered Dec 24 '22 03:12

Walter Chang


List.slice and List.filter both return Lists -- which are by definition immutable.The + and - methods return a different List, they do not change the original List. Also, it is hard to do better than O(N). A List is not random access, it is a linked list. So imagine if the sublist that you want is the last element of the List. The only way to access that element is to iterate over the entire List.

like image 45
michaelg Avatar answered Dec 24 '22 03:12

michaelg