val monies: Map[String, Double] = Map(
"USD-EUR" -> 0.7473154,
"EUR-GBP" -> 0.0097373,
"GBP-USD" -> 136.6080875,
"COL-USD" -> 1.0000000,
"ABC-XYZ" -> 1.00034500,
"XYZ-ABC" -> 1.000345000
)
I want to create a List[Map[String, Double]] which has every possible combination of the Map above.
In the final List of Maps, each Map must have a minimum of three currencies (i.e. any Maps with less than 3 entries must be excluded).
The Map provided may have 3 currencies or may have 50. Meaning the solution must be scalable for example if any new country was established along with a new currency.
List(
Map(
"USD-EUR" -> 0.7473154,
"EUR-GBP" -> 0.0097373,
"GBP-USD" -> 136.6080875
),
Map(
"EUR-GBP" -> 0.0097373,
"USD-EUR" -> 0.7473154,
"GBP-USD" -> 136.6080875
),
Map(
"EUR-GBP" -> 0.0097373,
"GBP-USD" -> 136.6080875,
"USD-EUR" -> 0.7473154
),
Map(
"USD-EUR" -> 0.7473154,
"EUR-GBP" -> 0.0097373,
"GBP-USD" -> 136.6080875,
"COL-USD" -> 1.0000000,
),
Map(
"EUR-GBP" -> 0.0097373,
"USD-EUR" -> 0.7473154,
"GBP-USD" -> 136.6080875,
"COL-USD" -> 1.0000000,
),
.... etc etc
)
Please note unique can mean a different a different order of the entries. Also different length of Map size. Key must point to original values.
It seems all you need is this:
def getSubMaps[K, V](map: Map[K, V]): Iterator[Map[K, V]] =
map
.keySet
.subsets
.filter(keys => keys.sizeIs >= 3)
.map(keys => keys.map(key => key -> map(key)).toMap)
Since the result can be too big it is better to return an Iterator that will lazily produce the values required. You can always call toList at the end if you really need all of them in memory.
As I always say, the Scaladoc is your friend.
Related
I have some metrics data like below, it's Map[String, Any], I want to get the data from Map, e.g. I want to get non_unique -> 1 from metrics data.
Map(applicationId -> local-1673262860096, job_name -> dist_batch, tmst -> 1673262884352, measure_name -> duplication_measure, metrics -> WrappedArray( Map(metric_name -> total, metric_value -> 50), Map(metric_name -> duplicate, metric_value -> 1), Map(metric_name -> unique, metric_value -> 48), Map(metric_name -> non_unique, metric_value -> 1), Map(metric_name -> distinct, metric_value -> 49) ), measure_type -> Duplication, data_source -> source)
I try to use val metricToInvestigate= metrics.get("metrics").get, but find that metricToInvestigate becomes to Any type, but I don't know how to get the output like non_unique -> 1
You gotta cast it:
val metricsMap: Map[String, Int] =
metrics("metrics")
.asInstanceOf[Seq[Map[String,Int]]]
.map { m => m("metric_name") -> m("metric_value") }
.toMap
So I have a list of maps like this
val data = List(
Map[String, String]("name" -> "Bob", "food" -> "pizza", "day" -> "monday"),
Map[String, String]("name" -> "Ron", "food" -> "hotdog", "day" -> "tuesday"),
Map[String, String]("name" -> "Tim", "food" -> "pizza", "day" -> "wednesday"),
Map[String, String]("name" -> "Carl", "food" -> "hotdog", "day" -> "wednesday")
)
I want to make a Map like this from that List of maps
val result = Map("pizza" -> Map("name" -> ("Bob", "Tim"), "day" -> ("monday", "wednesday")),
"hotdog"-> Map("name" -> ("Ron", "Carl"), "day" -> ("tuesday", "wednesday")))
How can I achieve this result? Thanks
*ps I'm a beginner in Scala
Here is a preliminary solution, there is probably an easier way of doing this with fold but I have to sketch that out separately
data.groupMap(a => a("food"))(_.filter(_._1 != "food"))
.map{
case (a,b) =>
(a, b.flatten.groupMapReduce(_._1)(a => List(a._2))(_ ++ _))}
You group the maps inside based on the value of food
This gives you:
Map(
hotdog -> List(
Map(name -> Ron, food -> hotdog, day -> tuesday),
Map(name -> Carl, food -> hotdog, day -> wednesday)),
pizza -> List(
Map(name -> Bob, food -> pizza, day -> monday),
Map(name -> Tim, food -> pizza, day -> wednesday))
)
You remove the key food from the inner maps
Map(
hotdog -> List(
Map(name -> Ron, day -> tuesday),
Map(name -> Carl, day -> wednesday)),
pizza -> List(
Map(name -> Bob, day -> monday),
Map(name -> Tim, day -> wednesday))
)
You "merge" the maps inside by using groupMapReduce which
a) groups by the inner key (i.e. name and day)
b) maps each value to a singleton list
c) concats the lists
Edit: Here is a single pass solution using foldLeft but I don't think I like this any better. All the key accesses are unsafe and will blow up if your entry is missing the key. So ideally you would need to use .get() to get back an option and do bunch of pattern matching
data.foldLeft(Map[String, Map[String, List[String]]]())((b, a) => {
val foodVal = a("food")
b.get(foodVal) match{
case None => b + (foodVal ->
List("name" -> List(a("name")), "day" -> List(a("day"))).toMap)
case Some(v : Map[String, List[String]]) =>
b + (foodVal ->
List("name" -> (v("name") :+ a("name")), "day" -> (v("day") :+ a("day"))).toMap)
}
})
need your help,
i'm just a newbie that come to Scala Programming.
i have some map like sample below
Map(Y1A0001_001 -> CU, Y1D0003 -> A011, Y1C0002 -> 20211030, Y1D0000 -> four, Y1D0002 -> Today only, Y1C0001 -> 123123, Y1B0003 -> 005, Y1D0001 -> CitizenID, Y1C0000 -> Customer)
Map(Y1A0001_001 -> CU, Y1D0003 -> A011, Y1C0002 -> 20210928, Y1D0000 -> five, Y1D0002 -> Today only, Y1C0001 -> 133213, Y1B0003 -> 006, Y1D0001 -> Drive License, Y1C0000 -> Director)
Map(Y1A0001_001 -> CU, Y1D0003 -> A011, Y1C0002 -> 20210927, Y1D0000 -> six, Y1D0002 -> Both, Y1C0001 -> 452234324, Y1B0003 -> 007, Y1D0001 -> CitizenID, Y1C0000 -> Messenger)
How can i find the key that contain suffix 001 and get the value too in Scala programming?
for example the key is Y1A0001_001 and value is "CU"
please forgive me if my question is not clear enough
Thank you before for your help
val map: Map[String, String] = ???
val result: Option[(String, String)] = map.find { case (k,v) =>
k.endsWith("001")
}
See Scaladoc: https://www.scala-lang.org/api/current/scala/collection/Map.html#find(p:A=%3EBoolean):Option[A]
I have a map in my scala code, that has a string as a key and a userdefined object as the value. I want to split this map to three different map objects based on a property of the value.
Is this possible? Can someone share a way to do this? I have been trying to search but no example could be found. I am a novice at scala and appreciate any help...
Lets say you had a map of person's and you wanted to divide that into three maps based on the age of a person.
case class Person(name: String, age: Int)
val map = Map(
"p1" -> Person("person_1", 15),
"p2" -> Person("person_2", 30),
"p3" -> Person("person_3", 40),
"p4" -> Person("person_4", 55),
"p5" -> Person("person_5", 65)
)
// map: scala.collection.immutable.Map[String,Person] = Map(p4 -> Person(person_4,55), p5 -> Person(person_5,65), p3 -> Person(person_3,40), p2 -> Person(person_2,30), p1 -> Person(person_1,15))
val dividedMaps = map.groupBy({ case (key, person) =>
if (person.age < 20 ) "teenager"
else if (person.age < 50) "adult"
else "old"
})
// dividedMaps: scala.collection.immutable.Map[String,scala.collection.immutable.Map[String,Person]] = Map(old -> Map(p4 -> Person(person_4,55), p5 -> Person(person_5,65)), teenager -> Map(p1 -> Person(person_1,15)), adult -> Map(p3 -> Person(person_3,40), p2 -> Person(person_2,30)))
How to sort Map[Int,Map[String,String]]?
var data=Map(1416479696353 -> Map(name -> You,savePoint -> 4), 1416479788969 -> Map(name -> You, savePoint -> 9), 1416479801372 -> Map(name -> govind,savePoint -> 10))
i want to sort above map according to savePoint
Use sortBy:
data.toSeq.sortBy(_._2("savePoint").toInt)
This will give you a List[(Int, Map[String, String])]. If you only need the values of data, you can sort data.values.toSeq instead.