Scala How to get sublist by index - scala

I have a List(1 ,2 ,3 ,4 ,5) and trying to get a sublist: List(3, 4) from it by the following way:
List(1 ,2 ,3 ,4 ,5).slice(this.size - 3 , this.size - 1 )
But I got an error
error: value size is not a member of object
How can I use "this" parameter in Scala just like in Java. Are there other ways to achieve the goal. Thank you so much.

You should first declare the list, and then refer to the list using its name list, not this:
val list = List(1 ,2 ,3 ,4 ,5)
list.slice(list.size -3, list.size -1)
If you really want to do this in one line, then use reverse, but it's not very efficient:
List(1 ,2 ,3 ,4 ,5).reverse.slice(1, 3).reverse
By the way, that code wouldn't be valid in Java either. this refers to the enclosing object, not to the list.

If you want last 3 or n elements, you can use takeRight(3) or takeRight(n).
Edit based on the question edit:
If you need to not take first f and last l elements then
List(1,2,3,....n).drop(f).dropRight(l)
For your case it will be List(1,2,3,4,5).drop(2).dropRight(1)

The problem is that the word this is not pointing your List, if you want to take some parameter in the middle of the List use take and takeRigth please read the Scala Docs at the end is a link
val my_lst = List(1 ,2 ,3 ,4 ,5)
my_lst.takeRight(3).take(2)
my_lst: List[Int] = List(1, 2, 3, 4, 5)
res0: List[Int] = List(3, 4)
first takeRight with the index counting on right my_lst.size - thepositions, so you must write thepositions and then how many elements you want in your new subList
Here is a explanations of how work the methods in scala List
from Scala Help Doc
def slice(from: Int, until: Int): List[A]
returns
a list containing the elements greater than or equal to index from extending up to (but not including) index until of this list.
Definition Classes
List → LinearSeqOptimized → IterableLike → TraversableLike → GenTraversableLike Example:
// Given a list
val letters = List('a','b','c','d','e')
// slice returns all elements beginning at index from and afterwards,
// up until index until (excluding index until.)
letters.slice(1,3) // Returns List('b','c')
in you case use length or size
scala> val my_lst = List(1 ,2 ,3 ,4 ,5)
my_lst: List[Int] = List(1, 2, 3, 4, 5)
scala> my_lst.slice(my_lst.length-3,my_lst.length)
res0: List[Int] = List(3, 4, 5)
but really scala List class has a lot of functions that can fit you. In your case if you want the last 3 elemments use takeRight
def takeRight(n: Int): List[A]
Selects last n elements.
n
the number of elements to take returns
a list consisting only of the last n elements of this list, or else the whole list, if it has less than n elements.
Definition Classes
List → IterableLike
scala> my_lst.takeRight(3)
res2: List[Int] = List(3, 4, 5)
Take a look at the Scala Docs

You have a List(1, 2, 3, 4, 5)
1) Is that a Function or Object or a Class?
2) You want to use return values from List( x , x , 3 , 4 , x )
3) you need to use size outside of the parentheses to return the value from your new List function...
4) create a function to complete this step then return it to a variable...
5) when you fire the function List() use variables with List( A , B , C , D , E )
6) all objects must be completely declared before use. for example, How can you use a basketball without air inside? or How can you use a football without being covered in pigskin? or How can you use a computer without a CPU? all components of objects must be completely declared and working properly in programming!
7) All data, functions, objects inside your List() function must be working properly or ... functioning . . .
8) You said "In general I also want to get some elements in the middle" ..
9) As a veteran programmer... You have to know exactly where the elements are in your List() function
10) Also from the start, before all these functions you wish to "use" you must load the classes, that is filled with all the functions you use, at the head of your program.
11) you cannot use a function the same way you use an object or a class!
12) Lastly, you just want to be creative when the programming language sets the rules or boundaries ...Scala is not Java ...
Does this help? with "error: value size is not a member of object"

Related

What is the difference between partition and groupBy?

I am reading through Twitter's Scala School right now and was looking at the groupBy and partition methods for collections. And I am not exactly sure what the difference between the two methods is.
I did some testing on my own:
scala> List(1, 2, 3, 4, 5, 6).partition(_ % 2 == 0)
res8: (List[Int], List[Int]) = (List(2, 4, 6),List(1, 3, 5))
scala> List(1, 2, 3, 4, 5, 6).groupBy(_ % 2 == 0)
res9: scala.collection.immutable.Map[Boolean,List[Int]] = Map(false -> List(1, 3, 5), true -> List(2, 4, 6))
So does this mean that partition returns a list of two lists and groupBy returns a Map with boolean keys and list values? Both have the same "effect" of splitting a list into two different parts based on a condition. I am not sure why I would use one over the other. So, when would I use partition over groupBy and vice-versa?
groupBy is better suited for lists of more complex objects.
Say, you have a class:
case class Beer(name: String, cityOfBrewery: String)
and a List of beers:
val beers = List(Beer("Bitburger", "Bitburg"), Beer("Frueh", "Cologne") ...)
you can then group beers by cityOfBrewery:
val beersByCity = beers.groupBy(_.cityOfBrewery)
Now you can get yourself a list of all beers brewed in any city you have in your data:
val beersByCity("Cologne") = List(Beer("Frueh", "Cologne"), ...)
Neat, isn't it?
And I am not exactly sure what the difference between the two methods
is.
The difference is in their signature. partition expects a function A => Boolean while groupBy expects a function A => K.
It appears that in your case the function you apply with groupBy is A => Boolean too, but you don't want always to do this, sometimes you want to group by a function that don't always returns a boolean based on its input.
For example if you want to group a List of strings by their length, you need to do it with groupBy.
So, when would I use partition over groupBy and vice-versa?
Use groupBy if the image of the function you apply is not in the boolean set (i.e f(x) for an input x yield another result than a boolean). If it's not the case then you can use both, it's up to you whether you prefer a Map or a (List, List) as output.
Partition is when you need to split some collection into two basing on yes/no logic (even/odd numbers, uppercase/lowecase letters, you name it). GroupBy has more general usage: producing many groups, basing on some function. Let's say you want to split corpus of words into bins depending on their first letter (resulting into 26 groups), it simply not possible with .partition.

Replace an element in a sorted set in scala

How do I replace the first element in a sorted set in Scala? Is there an analogous function to 'patch' for Sorted Sets? Is it even possible?
val a = SortedSet(1,5,6)
val b = a.patch(0, seq[2], 1)
println(b)
Result should be:
TreeSet(2, 5, 6)
How about this:
scala> val a = SortedSet(1,5,6)
a: scala.collection.SortedSet[Int] = TreeSet(1, 5, 6)
scala> val b = a.drop(1) + 2
b: scala.collection.SortedSet[Int] = TreeSet(2, 5, 6)
Note: You're not really replacing anything here (at least not like an array.) What you are doing is taking a SortedSet and using drop to remove the first element (which happens to be the lowest value in sorted order in this case) and then you are adding another element to the set. 2 is only in the first position because that is where it is supposed to be in sorted order.
scala> a.drop(1) + 10
res21: scala.collection.SortedSet[Int] = TreeSet(5, 6, 10)
As you see, if you add 10, it also takes its place in sorted order which is at the end.
Furthermore, because sets cannot contain duplicates, doing something like:
scala> a.drop(1) + 6
res22: scala.collection.SortedSet[Int] = TreeSet(5, 6)
removes the first element and leaves you with only two elements in the set. This is because 6 was already in the set, so it is not added (again, a property of a set is that it does not contain duplicates.)

In Scala, how to get a slice of a list from nth element to the end of the list without knowing the length?

I'm looking for an elegant way to get a slice of a list from element n onwards without having to specify the length of the list. Lets say we have a multiline string which I split into lines and then want to get a list of all lines from line 3 onwards:
string.split("\n").slice(3,X) // But I don't know what X is...
What I'm really interested in here is whether there's a way to get hold of a reference of the list returned by the split call so that its length can be substituted into X at the time of the slice call, kind of like a fancy _ (in which case it would read as slice(3,_.length)) ? In python one doesn't need to specify the last element of the slice.
Of course I could solve this by using a temp variable after the split, or creating a helper function with a nice syntax, but I'm just curious.
Just drop first n elements you don't need:
List(1,2,3,4).drop(2)
res0: List[Int] = List(3, 4)
or in your case:
string.split("\n").drop(2)
There is also paired method .take(n) that do the opposite thing, you can think of it as .slice(0,n).
In case you need both parts, use .splitAt:
val (left, right) = List(1,2,3,4).splitAt(2)
left: List[Int] = List(1, 2)
right: List[Int] = List(3, 4)
The right answer is takeRight(n):
"communism is sharing => resource saver".takeRight(3)
//> res0: String = ver
You can use scala's list method 'takeRight',This will not throw exception when List's length is not enough, Like this:
val t = List(1,2,3,4,5);
t.takeRight(3);
res1: List[Int] = List(3,4,5)
If list is not longer than you want take, this will not throw Exception:
val t = List(4,5);
t.takeRight(3);
res1: List[Int] = List(4,5)
get last 2 elements:
List(1,2,3,4,5).reverseIterator.take(2)

Get item in the list in Scala?

How in the world do you get just an element at index i from the List in scala?
I tried get(i), and [i] - nothing works. Googling only returns how to "find" an element in the list. But I already know the index of the element!
Here is the code that does not compile:
def buildTree(data: List[Data2D]):Node ={
if(data.length == 1){
var point:Data2D = data[0] //Nope - does not work
}
return null
}
Looking at the List api does not help, as my eyes just cross.
Use parentheses:
data(2)
But you don't really want to do that with lists very often, since linked lists take time to traverse. If you want to index into a collection, use Vector (immutable) or ArrayBuffer (mutable) or possibly Array (which is just a Java array, except again you index into it with (i) instead of [i]).
Safer is to use lift so you can extract the value if it exists and fail gracefully if it does not.
data.lift(2)
This will return None if the list isn't long enough to provide that element, and Some(value) if it is.
scala> val l = List("a", "b", "c")
scala> l.lift(1)
Some("b")
scala> l.lift(5)
None
Whenever you're performing an operation that may fail in this way it's great to use an Option and get the type system to help make sure you are handling the case where the element doesn't exist.
Explanation:
This works because List's apply (which sugars to just parentheses, e.g. l(index)) is like a partial function that is defined wherever the list has an element. The List.lift method turns the partial apply function (a function that is only defined for some inputs) into a normal function (defined for any input) by basically wrapping the result in an Option.
Why parentheses?
Here is the quote from the book programming in scala.
Another important idea illustrated by this example will give you insight into why arrays are accessed with parentheses in Scala. Scala has fewer special cases than Java. Arrays are simply instances of classes like any other class in Scala. When you apply parentheses surrounding one or more values to a variable, Scala will transform the code into an invocation of a method named apply on that variable. So greetStrings(i) gets transformed into greetStrings.apply(i). Thus accessing an element of an array in Scala is simply a method call like any other. This principle is not restricted to arrays: any application of an object to some arguments in parentheses will be transformed to an apply method call. Of course this will compile only if that type of object actually defines an apply method. So it's not a special case; it's a general rule.
Here are a few examples how to pull certain element (first elem in this case) using functional programming style.
// Create a multdimension Array
scala> val a = Array.ofDim[String](2, 3)
a: Array[Array[String]] = Array(Array(null, null, null), Array(null, null, null))
scala> a(0) = Array("1","2","3")
scala> a(1) = Array("4", "5", "6")
scala> a
Array[Array[String]] = Array(Array(1, 2, 3), Array(4, 5, 6))
// 1. paratheses
scala> a.map(_(0))
Array[String] = Array(1, 4)
// 2. apply
scala> a.map(_.apply(0))
Array[String] = Array(1, 4)
// 3. function literal
scala> a.map(a => a(0))
Array[String] = Array(1, 4)
// 4. lift
scala> a.map(_.lift(0))
Array[Option[String]] = Array(Some(1), Some(4))
// 5. head or last
scala> a.map(_.head)
Array[String] = Array(1, 4)
Please use parentheses () to access the list of elements, as shown below.
list_name(index)

How to do something like this in Scala?

Sorry for the lack of a descriptive title; I couldn't think of anything better. Edit it if you think of one.
Let's say I have two Lists of Objects, and they are always changing. They need to remain as separate lists, but many operations have to be done on both of them. This leads me to doing stuff like:
//assuming A and B are the lists
A.foo(params)
B.foo(params)
In other words, I'm doing the exact same operation to two different lists at many places in my code. I would like a way to reduce them down to one list without explicitly having to construct another list. I know that just combining lists A and b into a list C would solve all my problems, but then we'd just be back to the same operation if I needed to add a new object to the list (because I'd have to add it to C as well as its respective list).
It's in a tight loop and performance is very important. Is there any way to construct an iterator or something that would iterate A and then move on to B, all transparently? I know another solution would be to construct the combined list (C) every time I'd like to perform some kind of function on both of these lists, but that is a huge waste of time (computationally speaking).
Iterator is what you need here. Turning a List into an Iterator and concatenating 2 Iterators are both O(1) operations.
scala> val l1 = List(1, 2, 3)
l1: List[Int] = List(1, 2, 3)
scala> val l2 = List(4, 5, 6)
l2: List[Int] = List(4, 5, 6)
scala> (l1.iterator ++ l2.iterator) foreach (println(_)) // use List.elements for Scala 2.7.*
1
2
3
4
5
6
I'm not sure if I understand what's your meaning.
Anyway, this is my solution:
scala> var listA :List[Int] = Nil
listA: List[Int] = List()
scala> var listB :List[Int] = Nil
listB: List[Int] = List()
scala> def dealWith(op : List[Int] => Unit){ op(listA); op(listB) }
dealWith: ((List[Int]) => Unit)Unit
and then if you want perform a operator in both listA and listB,you can use like following:
scala> listA ::= 1
scala> listB ::= 0
scala> dealWith{ _ foreach println }
1
0