Taking the Vector out of Some - scala

In my code, after an API call, I am getting
Some(Vector(72981, 72982)).
I need to get the vector out of Some so that I modify the vector. Tried many things but no result.

Using map you can modify what's in the Option (i.e. the Some in this case)
Some(Vector(72981, 72982)).map(vector => // do something with vector)
// Some(modifiedVector)
this will return the modified vector inside an Option.
If you want to extract the value from the Option, you can use getOrElse
val v = Some(Vector(72981, 72982)).getOrElse(/* a fallback value */)
or a match
val opt = Some(Vector(72981, 72982))
opt match {
case Some(vector) => // do something with vector
case None => // vector doesn't exist
}

Related

How to map() method output and not the method itself?

I'm new to Scala and created a infinite Stream of int and want to map() for each int i, the computed value x, which results from method m(i) = x. The point is, that I want the stream to actually stop when x > 0, AND I need the i which was used to compute the HIGHEST x of the list. However I'm struggling with this task, since I get an UnsupportedOperationException empty.max...
I tried using the code below, throwing the described exception. I also tried to create tuple out of (i,m(i)), but instead of actually applying m(i), the method itself got mapped.
This is method m:
def m(t: Int): Double = {
//Some calculation...
}
Ant I tried these options:
Stream.from(1).map(m(_)).takeWhile(_ > 0).toList.max
Stream.from(1).map((_,m(_))).takeWhile(_._2.apply(1) > 0).maxBy(_._2)
The second one shows this:
missing parameter type for expanded function ((x$2: <error>) => m(x$2)) Stream.from(1).map((_,m(_))).takeWhile(_._2.apply(1) > 0).maxBy(_._2)
How can I resolve this as short as possible? Thank you very much guys!
.map((_,m(_)))
This means i => (i, j => m(j)), not i => (i, m(i)) which you want. So just write map(i => (i, m(i))) (or as Luis suggests, i -> m(i)) explicitly. I'd personally prefer braces for this lambda: map { i => (i, m(i)) }.

Reduce list of tuples to a single tuple in scala

Item is a custom type.
I have a Iterable of pairs (Item, Item). The first element in every pair is the same, so I want to reduce the list to a single pair of type (Item, Array[Item])
// list: Iterable[(Item, Item)]
// First attempt
val res = list.foldLeft((null, Array[Item]()))((p1,p2) => {
(p2._1, p1._2 :+ p2._2)
}
// Second attempt
val r = list.unzip
val res = (r._1.head, r._2.toArray))
1. I don't know how to correctly setup the zero value in the first ("foldLeft") solution. Is there any way to do something like this?
2. Other than the second solution, is there a better way to reduce a list of custom object tuples to single tuple ?
If you are sure the first element in every pair is the same, why don't you use that information to simplify?
(list.head._1, list.map(_._2))
should do the work
if there are other cases where the first element is different, you may want to try:
list.groupBy(_._1).map { case (common, lst) => (common, lst.map(_._2)) }

scala help need to understand AssociationRules creation

A newbie qustion. I try to learn Scala from examples , I found some Spark code that creates AssociationRules source code here
def run[Item: ClassTag](freqItemsets: RDD[FreqItemset[Item]]): RDD[Rule[Item]] = {
// For candidate rule X => Y, generate (X, (Y, freq(X union Y)))
val candidates = freqItemsets.flatMap { itemset =>
val items = itemset.items
items.flatMap { item =>
items.partition(_ == item) match {
case (consequent, antecedent) if !antecedent.isEmpty =>
Some((antecedent.toSeq, (consequent.toSeq, itemset.freq)))
case _ => None
}
}
}
I try to undersatnd how the run function works and how the algorithm understands incase that antecedent is X and consequent is Y. How are the items divided?
Another question: how does the join function work (below)? is freqAntecedent is x.freq ? How does freqUnion apprear in map?
candidates.join(freqItemsets.map(x => (x.items.toSeq, x.freq)))
.map { case (antecendent, ((consequent, freqUnion), freqAntecedent)) =>
new Rule(antecendent.toArray, consequent.toArray, freqUnion, freqAntecedent)
}.filter(_.confidence >= minConfidence)
Thanks for any help !
generate (X, (Y, freq(X union Y))) means that the items are pairs (2-Tuple) of values. A Tuple has an unapply method that allows pattern matching on it, i.e exactly what you see in the case statement. Any time a class implements unapply, you can use it in a case statement where you can break it up into its attributes and assign each attribute to a variable.

Convert Scala foreach to .map

I'm new to Scala and I'm trying to convert code of the form
val series: ListBuffer[Seq[Seq[Any]]] = ListBuffer[Seq[Seq[Any]]]()
points.foreach(point => {
if( conditionA )
series += doA(...) // returns a ListBuffer[Seq[Any]]
else
series += doB(...) // returns a ListBuffer[Seq[Any]]
})
to use .map(). I'm thinking its something like:
val series: ListBuffer[Seq[Seq[Any]]] = points.map(point => {
case conditionA => doA(...)
case _ => doB(...)
})
but this doesn't compile because (I believe) the mapped sequences get appended as a single Seq[Any] instead of Seq[Seq[Any]], so I get the error
Expression of type Seq[Any] doesn't conform to expected type ListBuffer[Seq[Seq[Any]]]
Any ideas? Is there something wrong with syntax?
Let me suppose a few things, you have some function def doA(arg1: A): ListBuffer[Seq[Any]] such that you ultimately want to arrive at a List[Seq[Any]] as the final result type after mapping this function over your collection. Then what you want is flatMap instead of map:
val series = points flatMap{
case point if conditionA(point) => doA(point) result ()
case point => doB(point) result ()
}
The reason I make such a supposition is that the only reason you'd ever want to use a ListBuffer[A] in the general form is to create a List[A] through some side-effecting expression. Hence, you ultimately want a List[Seq[A]] as your final output.

Handle Scala Option idiomatically

What is the more idiomatic way to handle an Option, map / getOrElse, or match?
val x = option map {
value => Math.cos(value) + Math.sin(value)
} getOrElse {
.5
}
or
val x = option match {
case Some(value) => Math.cos(value) + Math.sin(value)
case None => .5
}
You could always just look at the Scaladoc for Option:
The most idiomatic way to use an scala.Option instance is to treat it as a collection or monad and use map,flatMap, filter, or foreach:
val name: Option[String] = request getParameter "name"
val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase }
println(upper getOrElse "")
And a bit later:
A less-idiomatic way to use scala.Option values is via pattern matching:
val nameMaybe = request getParameter "name"
nameMaybe match {
case Some(name) =>
println(name.trim.toUppercase)
case None =>
println("No name value")
}
Use fold for this kind of map-or-else-default thing:
val x = option.fold(0.5){ value => Math.cos(value) + Math.sin(value) }
Obviously both are valid and I don't think one is more idiomatic than the other. That being said, using map uses the fact the Option is a Monad. This can be particularly advantageous when combining two Options. Say you have two Option[Int] that you would like to add. In this case instead of doing multiple matches it is much cleaner to use map/flatMap and it's equivalent "for comprehensions". So for your example both are valid... but for other examples using map/flatMap is often much more succinct.
Some(6).flatMap(intValue => Some(5).map(intValue + _))
or
for {
i <- Some(6)
j <- Some(5)
} yield i + j
All of them have different semantics, so in your case none of them.
map applies some function to the value inside Option, if it exists (Some, not None). Basically this is how you safely work with Options, appling function on some null value is dangeroues, cause it can throw NPE, but in case with Option it just returns None.
getOrElse simply returns either it's value or default one (which you provide as an argument). It won't do anything with the value inside the Option, you can just extract it, if you have Some, or return a default one, in case of None.
and match approach i'd say is a combination of two, cause you can apply some computation on the values and extract it from the Option