Replace an element in a sorted set in scala - 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.)

Related

How to change elements of set in scala

In scala, you can have 2 types of set where the elements are immutable or mutable, But as you cannot index these sets, so how can you change the elements of the latter sets??
In scala, you can have 2 types of set where the elements are immutable or mutable
That is not what the distinction between scala.collection.immutable.Set and scala.collection.mutable.Set is. It is not about mutability or immutability of the elements, it is about mutability or immutability of the sets themselves.
But as you cannot index these sets, so how can you change the elements of the latter sets
It is not about changing the elements of mutable sets. It is about changing the mutable sets themselves:
import scala.collection.mutable.{ Set => MSet}
import scala.collection.immutable.{Set => ISet}
val mset = MSet(1, 2, 3)
val iset = ISet(1, 2, 3)
mset += 4
mset //=> HashSet(1, 2, 3, 4): scala.collection.mutable.Set[Int]
val iset2 = iset + 4
iset //=> Set(1, 2, 3): scala.collection.immutable.Set[Int]
iset2 //=> Set(1, 2, 3, 4): scala.collection.immutable.Set[Int]
iset += 4
// ERROR: value += is not a member of scala.collection.immutable.Set[Int]
[Scastie link]
The difference between the two is that you can't add an element to an immutable set. Instead, when you call the scala.collection.immutable.Set.+(elem: A): Set[A] method, it will return a new set (iset2 in this case) that has the same elements as the original set (iset) plus the element we wanted to add.
Whereas the scala.collection.mutable.Set.+=(elem: A): Set.this.type method returns the same set (and in fact, as you can see in my example above, I actually ignore the return value) and mutates it to contain the additional element.
In Scala, the idea of a set is much closer to the mathematical idea of sets instead of as a collection. It is not a collection that contains the elements, rather it is a predicate function that you can ask "is this element a member of the set"?

Scala - create a new list and update particular element from existing list

I am new to Scala and new OOP too. How can I update a particular element in a list while creating a new list.
val numbers= List(1,2,3,4,5)
val result = numbers.map(_*2)
I need to update third element only -> multiply by 2. How can I do that by using map?
You can use zipWithIndex to map the list into a list of tuples, where each element is accompanied by its index. Then, using map with pattern matching - you single out the third element (index = 2):
val numbers = List(1,2,3,4,5)
val result = numbers.zipWithIndex.map {
case (v, i) if i == 2 => v * 2
case (v, _) => v
}
// result: List[Int] = List(1, 2, 6, 4, 5)
Alternatively - you can use patch, which replaces a sub-sequence with a provided one:
numbers.patch(from = 2, patch = Seq(numbers(2) * 2), replaced = 1)
I think the clearest way of achieving this is by using updated(index: Int, elem: Int). For your example, it could be applied as follows:
val result = numbers.updated(2, numbers(2) * 2)
list.zipWithIndex creates a list of pairs with original element on the left, and index in the list on the right (indices are 0-based, so "third element" is at index 2).
val result = number.zipWithIndex.map {
case (n, 2) => n*2
case n => n
}
This creates an intermediate list holding the pairs, and then maps through it to do your transformation. A bit more efficient approach is to use iterator. Iterators a 'lazy', so, rather than creating an intermediate container, it will generate the pairs one-by-one, and send them straight to the .map:
val result = number.iterator.zipWithIndex.map {
case (n, 2) => n*2
case n => n
}.toList
1st and the foremost scala is FOP and not OOP. You can update any element of a list through the keyword "updated", see the following example for details:
Signature :- updated(index,value)
val numbers= List(1,2,3,4,5)
print(numbers.updated(2,10))
Now here the 1st argument is the index and the 2nd argument is the value. The result of this code will modify the list to:
List(1, 2, 10, 4, 5).

Can Lazy modify elements in Array in Scala?

I want to define an array, each element of array is a data set read from certain path in the file system, because the data reading is costly and the position in array to be visited is sparse, so I want to use Lazy modifier to realize that one data set will not be read until being visited. How can define this kind of array?
Yes,we can define it with view function.
Instead of (0 to 10).toArray
scala> val a=(0 to 10).toArray
a: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
View can not instantiate the array but when ever we call then only it executes
val a=(0 to 10).view
a: scala.collection.SeqView[Int,scala.collection.immutable.IndexedSeq[Int]] = SeqView(...)
scala> for (x <- a ){
| println(x)}
0
1
2
3
4
5
6
7
8
9
10
I hope this answered your question
No, you cannot use lazy on the array to make the elements lazy. The most natural thing to do would be to use a caching library like ScalaCache.
You can also make a kind of wrapper class with a lazy field as you suggested in your comment. However, I would prefer not to expose the caching to the clients of the array. You should be able to just write myArray(index) to access an element.
If you don't want to use a library, this is another option (without lazy) that gives you an array like object with caching:
class CachingArray[A](size: Int, getElement: Int => A) {
val elements = scala.collection.mutable.Map[Int, A]()
def apply(index: Int) = elements.getOrElseUpdate(index, getElement(index))
}
Just initialize it with the size and a function that computes an element at a given index.
If you like, you can make it extend IndexedSeq[A] so it can be used more like a real array. Just implement length like this:
override def length: Int = size

Scala How to get sublist by index

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"

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)