I was wondering what's the most efficient way to check if a map has a value equal or greater than a certain threshold:
for example, if I get the following map:
val x = Map(2 -> 2, 3 -> 1, 4 -> 1, 7 -> 1)
at the moment I wrote:
x.values.max > 2
Is there a more efficient way?
How to check if the Map contains a specific value instead?
You can use scala.collection.Iterator.exists to check whether there exists at least one item of a collection which satisfies a given predicate. To simplify iterating over the Map, you can use scala.collection.Map.valuesIterator:
x.valuesIterator.exists(_ > 2) //=> false
x.valuesIterator.exists(_ > 1) //=> true
Scastie link
Related
I'm just wondering why my grouping of values does not work in the code below. Technically, the Map and Set are both mutable so my add(intValue) should change the set (and indirectly the aggregator map).
import scala.collection.mutable._
val original = Iterator[(String, Int)](
"one" -> 1,
"two" -> 20,
"three" -> 30,
"one" -> 11
)
val folded = original.foldLeft(
Map[String, Set[Int]]().withDefaultValue(Set.empty))
{
case (agg, (strVal, intVal)) =>
//agg += ((strVal, agg(strVal) + intVal)) <-- option 1 works
agg(strVal).add(intVal) // <--- option 2 does not work
agg // <--- option 2 does not work
}
For option 1, the result is as expected ( a grouping of "one" -> Set(1, 11) ...)
For option 2 I get an empty Map.
.withDefaultValue does not add the value to Map.
Use .getOrElseUpdate(strVal, Set.empty).add(intVal) instead.
when you call get(key) on this map with a default value it never adds the key that you passed, from the looks of it, it adds another key something on the lines of a "null key" within the map for all default values, that's why you get the same Set each time you do a get, but its not the value you are looking for.
This question already has answers here:
Getting all key value pairs having the maximum value from a Scala map
(2 answers)
Closed 4 years ago.
Can anybody help how to get the the maximum value in a map along with its key.
For example map below:
Map(s -> 3, h -> 2, M -> 1, q-> 4)
I should get the key value (q -> 4) as the 4 is the highest.
I tried the max method,keys and values iterator. But none of the return both key and value.
You can use maxBy as
val map_values = Map("s" -> 3, "h" -> 2, "M" -> 1, "q"-> 4)
println(map_values.maxBy(_._2))
//(q,4)
You can get what you want as follows:
map.filter{case (k,v) => v == map.values.max}
With map.values.max you get the max value, and inserting it into the filter statement you obtain the whole key-value pair
How does this look like for you?
map.maxBy { case (key, value) => value }
I want to shuffle a scala list randomly.
I know i can do this by using scala.util.Random.shuffle
But here by calling this i will always get a new set of list. What i really want is that in some cases i want the shuffle to give me the same output always. So how can i achieve that?
Basically what i want to do is to shuffle a list randomly at first and then repeat it in the same order. For the first time i want to generate the list randomly and then based on some parameter repeat the same shuffling.
Use setSeed() to seed the generator before shuffling. Then if you want to repeat a shuffle reuse the seed.
For example:
scala> util.Random.setSeed(41L) // some seed chosen for no particular reason
scala> util.Random.shuffle(Seq(1,2,3,4))
res0: Seq[Int] = List(2, 4, 1, 3)
That shuffled: 1st -> 3rd, 2nd -> 1st, 3rd -> 4th, 4th -> 2nd
Now we can repeat that same shuffle pattern.
scala> util.Random.setSeed(41L) // same seed
scala> util.Random.shuffle(Seq(2,4,1,3)) // result of previous shuffle
res1: Seq[Int] = List(4, 3, 2, 1)
Let a be the seed parameter
Let b be the how many time you want to shuffle
There are two ways to kinda of do this
you can use scala.util.Random.setSeed(a) where 'a' can be any integer so after you finish your shuffling b times you can set the 'a' seed again and then your shuffling will be in the same order as your parameter 'a'
The other way is to shuffle List(1,2,3,...a) == 1 to a b times save that as a nested list or vector and then you can map it to your iterable
val arr = List(Bob, Knight, John)
val randomer = (0 to b).map(x => scala.util.Random.shuffle((0 to arr.size))
randomer.map(x => x.map(y => arr(y)))
You can use the same randomer for you other list you want to shuffle by mapping it
I am new to Scala and trying out the map function on a Map.
Here is my Map:
scala> val map1 = Map ("abc" -> 1, "efg" -> 2, "hij" -> 3)
map1: scala.collection.immutable.Map[String,Int] =
Map(abc -> 1, efg -> 2, hij -> 3)
Here is a map function and the result:
scala> val result1 = map1.map(kv => (kv._1.toUpperCase, kv._2))
result1: scala.collection.immutable.Map[String,Int] =
Map(ABC -> 1, EFG -> 2, HIJ -> 3)
Here is another map function and the result:
scala> val result1 = map1.map(kv => (kv._1.length, kv._2))
result1: scala.collection.immutable.Map[Int,Int] = Map(3 -> 3)
The first map function returns all the members as expected however the second map function returns only the last member of the Map. Can someone explain why this is happening?
Thanks in advance!
In Scala, a Map cannot have duplicate keys. When you add a new key -> value pair to a Map, if that key already exists, you overwrite the previous value. If you're creating maps from functional operations on collections, then you're going to end up with the value corresponding to the last instance of each unique key. In the example you wrote, each string key of the original map map1 has the same length, and so all your string keys produce the same integer key 3 for result1. What's happening under the hood to calculate result1 is:
A new, empty map is created
You map "abc" -> 1 to 3 -> 3 and add it to the map. Result now contains 1 -> 3.
You map "efg" -> 2 to 3 -> 2 and add it to the map. Since the key is the same, you overwrite the existing value for key = 3. Result now contains 2 -> 3.
You map "hij" -> 3 to 3 -> 3 and add it to the map. Since the key is the same, you overwrite the existing value for key = 3. Result now contains 3 -> 3.
Return the result, which is Map(3 -> 3)`.
Note: I made a simplifying assumption that the order of the elements in the map iterator is the same as the order you wrote in the declaration. The order is determined by hash bin and will probably not match the order you added elements, so don't build anything that relies on this assumption.
I need to find the number of (key , value) pairs in a Map in my Scala code. I can iterate through the map and get an answer but I wanted to know if there is any direct function for this purpose or not.
you can use .size
scala> val m=Map("a"->1,"b"->2,"c"->3)
m: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2, c -> 3)
scala> m.size
res3: Int = 3
Use Map#size:
The size of this traversable or iterator.
The size method is from TraversableOnce so, barring infinite sequences or sequences that shouldn't be iterated again, it can be used over a wide range - List, Map, Set, etc.