How can I fold the nth and (n+1)th elements into a new list in Scala? - list

Let's say I have List(1,2,3,4,5) and I want to get
List(3,5,7,9), that is, the sums of the element and the previous (1+2, 2+3,3+4,4+5)
I tried to do this by making two lists:
val list1 = List(1,2,3,4)
val list2 = (list1.tail ::: List(0)) // 2,3,4,5,0
for (n0_ <- list1; n1th_ <- list2) yield (n0_ + n1_)
But that combines all the elements with each other like a cross product, and I only want to combine the elements pairwise. I'm new to functional programming and I thought I'd use map() but can't seem to do so.

List(1, 2, 3, 4, 5).sliding(2).map(_.sum).to[List] does the job.
Docs:
def sliding(size: Int): Iterator[Seq[A]]
Groups elements in fixed size blocks by passing a "sliding window" over them (as opposed to partitioning them, as is done in grouped.)

You can combine the lists with zip and use map to add the pairs.
val list1 = List(1,2,3,4,5)
list1.zip(list1.tail).map(x => x._1 + x._2)
res0: List[Int] = List(3, 5, 7, 9)

Personally I think using sliding as Infinity has is the clearest, but if you want to use a zip-based solution then you might want to use the zipped method:
( list1, list1.tail ).zipped map (_+_)
In addition to being arguably clearer than using zip, it is more efficient in that the intermediate data structure (the list of tuples) created by zip is not created with zipped. However, don't use it with infinite streams, or it will eat all of your memory.

Related

Pattern match against List 'init' and 'last' instead of 'head' and 'tail'

I know that it's possible to easily pattern match against the head (or an arbitrary number of initial elements) and tail of a List:
val items = List(1, 2, 3, 4)
val first :: rest = items
println(first, rest) // 1, List(2, 3, 4)
However, I would like to do it the other way - can you use a pattern to get the init and last of the list?
val items = List(1, 2, 3, 4)
val rest ??? last = items
println(rest, last) // List(1, 2, 3), 4
In JavaScript this would look like:
const [...init, last] = items
You can use the :+ custom extractor object.
So the code would look like this:
val rest :+ last = items
However, note that this is equally inefficient than doing:
val last :: rest = items.reverse
But, if you then need to decompose rest again, then reversing it first will be more efficient.
Finally, remember both are unsafe since they will throw in case the List is empty.
This should work:
val xs :+ x = items
Check out: https://www.scala-lang.org/files/archive/api/2.12.0/scala/collection/Seq.html#:+(elem:A):Seq[A]

SML adding indices to a list

Given a generic list, return a list containing the same objects in a tuple with their index in the list.
For example:
f ["a", "b"];
- val it = [(0,"a") , (1,"b")] : (int * string) list
The function should be a one-liner, meaning no pattern matching, recursion, if/else, helper functions and let/local. So far i could only make a list of indices given the input list:
fun f lst = List.take((foldl (fn (x,list) => [(hd(list)-1)]#list) [length(lst)] (lst)),length(lst));
f [#"a",#"b"];
- val it = [0, 1]: int List.list;
I should add the list items to these indices in a tuple but i'm not sure how to do that.
Here is a hint for one way to solve it:
1) Using List.sub, create an anonymous function which sends an index i to the pair consisting of i and the lst element at index i.
2) Map this over the result obtained by calling List.tabulate on length lst and the function which sends x to x.
I was able to get this to work (on one line), but the result is ugly compared to a straightforward pattern-matching approach. Other than as a puzzle, I don't see the motivation for disallowing that which makes SML an elegant language.
It appears that i forgot the #i operator to access the i'th element of a tuple. The answer is the following:
fun f xs = List.take((foldr (fn (x,list) => [(#1(hd(list))-1,x)]#list) [(length(xs),hd(xs))] (xs)),length(xs));
f (explode "Hello");
- val it = [(0, #"H"), (1, #"e"), (2, #"l"), (3, #"l"), (4, #"o")]: (int * char) List.list;

Scala Lists of lists of integers

I am new to Scala and am a bit confused.
Given a list of lists List[List[Int]], how can one call a specific index of an element of each list, for example the second element of each list?
Simple:
val ints = List( List(1,2), List(3,4) )
val result = ints.map( l => l(1) )
This will produce (2,4).
While both of the other answers work, here is another version that is both safe to use and not complex. You can lift a Seq to a Function[Int, Option[A]] to make apply return Options instead of throwing exceptions. In Addition you can use flatMap instead of map{...}.flatten
List(List(1), List(1,2), List(1,2,3)).flatMap { xs =>
xs.lift(1)
}
// res1: List[Int] = List(2, 2)

Choosing the last element of a list

scala> last(List(1, 1, 2, 3, 5, 8))
res0: Int = 8
for having a result above, I wrote this code:
val yum = args(0).toInt
val thrill:
def last(a: List[Int]): List[Int] = {
println(last(List(args(0).toInt).last)
}
What is the problem with this code?
You can use last, which returns the last element or throws a NoSuchElementException, if the list is empty.
scala> List(1, 2, 3).last
res0: Int = 3
If you do not know if the list is empty or not, you may consider using lastOption, which returns an Option.
scala> List().lastOption
res1: Option[Nothing] = None
scala> List(1, 2, 3).lastOption
res2: Option[Int] = Some(3)
Your question is about List, but using last on a infinite collection (e.g. Stream.from(0)) can be dangerous and may result in an infinite loop.
Another version without using last (for whatever reason you might need it).
def last(L:List[Int]) = L(L.size-1)
You should better do:
val a = List(1,2,3) //your list
val last = a.reverse.head
Cleaner and less error-prone :)
Albiet this is a very old question, it might come handy that the performance impact of head and last operations seems to be laid out here http://docs.scala-lang.org/overviews/collections/performance-characteristics.html.
The recursive function last should following 2 properties. Your last function doesn't have any of them.
Requirement #1. An exit condition that does not call recursive
function further.
Requirement #2. A recursive call that reduces the elements that we began with.
Here are the problems I see with other solutions.
Using built in function last might not be an option in interview
questions.
Reversing and head takes additional operations, which the interviewer might ask to reduce.
What if this is a custom linked list without the size member?
I will change it to as below.
def last(a: List[Int]): Int = a match {
//The below condition defines an end condition where further recursive calls will not be made. requirement #1
case x::Nil => x
//The below condition reduces the data - requirement#2 for a recursive function.
case x:: xs => last(xs)
}
last(List(1,2,3))
Result
res0: Int = 3
In these types of questions the useful take and takeRight are often overlooked. Similar to last, one avoids the slow initial reversing of a list, but unlike last, can take the last (or first) n items as opposed to just a single one:
scala> val myList = List(1,2,3)
myList: List[Int] = List(1, 2, 3)
scala> myList.takeRight(2)
res0: List[Int] = List(2, 3)
scala> myList.takeRight(1)
res1: List[Int] = List(3)

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?
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)
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.
Well, you can't get better than O(n) for drop on a List. As for the rest:
def constantSlice[T](l: List[T], start: Int, end: Int): Iterator[T] =
l.drop(start).elements.take(end - start)
Both elements and take (on Iterator) are O(1).
Of course, an Iterator is not an Iterable, as it is not reusable. On Scala 2.8 a preference is given to returning Iterable instead of Iterator. If you need reuse on Scala 2.7, then Stream is probably the way to go.