Prepending Items to Scala Set - scala

In Scala I can prepend items to a List via:
scala> 1 :: 2 :: 3 :: Nil
res16: List[Int] = List(1, 2, 3)
What's the equivalent :: operator for a Scala Set?

I believe you're looking for +. It's not called "prepend", but "add". The reason is that Set doesn't guarantee an ordering for the inserted elements.
scala> val s = Set(1, 2, 3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> s + 3
res0: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> s + 4
res1: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)
scala> s + 4 + 5
res2: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

Related

Scala difference between (1 to 4).toSet and (1 to 4).to[scala.collection.immutable.Set]?

Scala difference between (1 to 4).to[scala.collection.immutable.Set] and (1 to 4).toSet?
scala> (1 to 4).toSet
res37: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)
scala> (1 to 4).to[scala.collection.immutable.Set]
res38: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)
scala> (1 to 4).to[Set]
res39: Set[Int] = Set(1, 2, 3, 4)
scala> Set(1 to 4:_*)
res14: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)
If you look at the implementation of toSet:
def toSet[B >: A]: immutable.Set[B] = to[immutable.Set].asInstanceOf[immutable.Set[B]]
you can see it's just an alias to to[]. So it's the same.
Note that from Scala 2.13 and up, it's to(Set). See doc and release note
They should all be the same, Set is just an alias like so
type Set[A] = immutable.Set[A]

Scala .init method example

Can you please explain what init method performs with respect to below list
i can see the result of new list says that last sequence is being omitted from the existing list.
val numbers = List(1, 2, 3, 4, 5)
val result = numbers.init
println(result)
.init and .last are the compliments to the .head and .tail methods.
val nums = List(1,2,3,4)
nums.head //res0: Int = 1
nums.tail //res1: List[Int] = List(2, 3, 4)
nums.init //res2: List[Int] = List(1, 2, 3)
nums.last //res3: Int = 4
def init: List[A] which selects all elements except the last.
l: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8)
scala> l.last
res58: Int = 8
scala> l.init
res59: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> val testList = List(1,2,3,4,5)
testList: List[Int] = List(1, 2, 3, 4, 5)
scala> testList.init
res0: List[Int] = List(1, 2, 3, 4)
scala> testList.last
res1: Int = 5
scala> testList.head
res2: Int = 1
scala> testList.tail
res3: List[Int] = List(2, 3, 4, 5)

partition an Array with offset

in Clojure I can partition a vector with offset step like
(partition 2 1 [1 2 3 4])
this returns a sequence of lists of n items each at offsets step apart.
for example the previous method returns
((1 2) (2 3) (3 4))
I just wonder how can I acheive the same in Scala
use sliding - Array(1, 2, 3, 4).sliding(2). This would give you an Iterator and you can just call e.g. toArray and get Array[Array[Int]] where internals are as desired.
There is function in the standard library sliding for this purpose
scala> val x = Array(1, 2, 3).sliding(2, 1)
x: Iterator[Array[Int]] = non-empty iterator
scala> x.next
res8: Array[Int] = Array(1, 2)
scala> x.next
res9: Array[Int] = Array(2, 3)
scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)
scala> l.sliding(2).toList
res0: List[List[Int]] = List(List(1, 2), List(2, 3), List(3, 4), List(4, 5))
I think this does what you need:
List(1,2,3,4).sliding(2,1).toList

takeWhile: also need first element failed the condition in scala

scala> List(1,2,3,4,5,6,7).takeWhile(i=>i<5)
res1: List[Int] = List(1, 2, 3, 4)
What if I also need to include 5 in the result?
Assuming that the function that you will be using is more complicated than the taking first 5 elements then,
You can do
scala> List(1,2,3,4,5,6,7)
res5: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> res5.takeWhile(_<5) ++ res5.dropWhile(_<5).take(1)
res7: List[Int] = List(1, 2, 3, 4, 5)
Also
scala> res5.span(_<5)
res8: (List[Int], List[Int]) = (List(1, 2, 3, 4),List(5, 6, 7))
scala> res8._1 ++ res8._2.take(1)
res10: List[Int] = List(1, 2, 3, 4, 5)
Also
scala> res5.take(res5.segmentLength(_<5, 0) + 1)
res17: List[Int] = List(1, 2, 3, 4, 5)
scala> res5.take(res5.indexWhere(_>5))
res18: List[Int] = List(1, 2, 3, 4, 5)
Edit
If this is not a parallelized computation and you won't be using the parallel collections:
var last = myList.head
val rem = myList.takeWhile{ x=>
last = x
x < 5
}
last :: rem
anonymous function forming a closure around the solution you want.
Previous Answer
I'd settle for the far less complicated:
.takeWhile(_ <= 5)
wherein you're just using the less than or equal operator.
List(1,2,3,4,5,6,7,8).takeWhile(_ <= 5)
This is best optimal solution for it

Converting immutable to mutable collections

What is the best way to convert collection.immutable.Set to collection.mutable.Set?
scala> var a=collection.mutable.Set[Int](1,2,3)
a: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
scala> var b=collection.immutable.Set[Int](1,2,3)
b: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> collection.mutable.Set(b.toArray:_*)
res0: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
scala> collection.mutable.Set(b.toSeq:_*)
res1: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
scala> collection.mutable.Set(b.toList:_*)
res2: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
Starting Scala 2.13, via factory builders applied with .to(factory):
Set(1, 2, 3).to(collection.mutable.Set)
// collection.mutable.Set[Int] = HashSet(1, 2, 3)
Prior to Scala 2.13 and starting Scala 2.10:
Set(1, 2, 3).to[collection.mutable.Set]
// collection.mutable.Set[Int] = Set(1, 2, 3)