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]
Related
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.
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)
}
})
I have something like this:
val m1 = Map(A -> List(("a","b"),("c","d"),("e","f")))
I want the result to be :
(Map(A -> List("a","b")), Map(A -> List ("c","d")), Map(A -> List("e","f")))
could anyone help?
Thanks
It's hard to tell what exactly you are trying to do, but here is a way to convert m1 to the desired structure:
val m1 = Map("A" -> List(("a","b"),("c","d"),("e","f")))
m1.toList.flatMap { case (key, tuple) =>
tuple.map(v => Map(key -> List(v._1, v._2)))
}
I have the following data:
List(Map("weight"->"1000","type"->"abc","match"->"first"),Map("weight"->"1000","type"->"abc","match"->"third"),Map("weight"->"182","type"->"bcd","match"->"second"),Map("weight"->"150","type"->"bcd","match"->"fourth"),Map("weight"->"40","type"->"aaa","match"->"fifth"))
After grouping by "type" i would want results of first "abc" then "bcd" then "aaa"
When I apply group by "type" the resulting map gives first key as aaa whereas I want the first key to be "abc" and all corresponding values.
how can I achieve this?
As mentioned in the comments you need a sorted map, which is not created by a simple group by. What you could do is:
val a = List(Map("weight"->"1000", "type"->"abc","match"->"first"), Map("weight"->"1000","type"->"abc","match"->"third"),Map("weight"->"182","type"->"bcd","match"->"second"), Map("weight"->"150","type"->"bcd","match"->"fourth"), Map("weight"->"40","type"->"aaa","match"->"fifth"))
val sortedGrouping = SortedMap.empty[String,String] ++ a.groupBy { x => x("type") }
println(sortedGrouping)
What you get (printed) is:
Map(aaa -> List(Map(weight -> 40, type -> aaa, match -> fifth)), abc -> List(Map(weight -> 1000, type -> abc, match -> first), Map(weight -> 1000, type -> abc, match -> third)), bcd -> List(Map(weight -> 150, type -> bcd, match -> fourth)), bcd -> List(Map(weight -> 182, type -> bcd, match -> second)))
I don't think there is out of the box solution for what you are trying to achieve. Map is used in two ways: get a value by a key, and iterate over it. The first part is unaffected by a sort order, so groupBy works perfectly well. The second part can be achieved by creating a list of keys in required order and then using that list to get key-value pairs from Map in a specific order. For example:
val xs = List(Map("weight"->"1000","type"->"abc","match"->"first"),
Map("weight"->"1000","type"->"abc","match"->"third"),
Map("weight"->"182","type"->"bcd","match"->"second"),
Map("weight"->"150","type"->"bcd","match"->"fourth"),
Map("weight"->"40","type"->"aaa","match"->"fifth"))
import collection.mutable.{ListBuffer, Set}
// List of types in the order of appearance in your list
val sortedKeys = xs.map(_("type")).distinct
//> sortedKeys: List[String] = List(abc, bcd, aaa)
Now when you need to iterate you simply do:
val grouped = xs.groupBy(_("type"))
sortedKeys.map(k => (k, grouped(k)))
// List[(String, List[scala.collection.immutable.Map[String,String]])] =
// List(
// (abc,List(Map(weight -> 1000, type -> abc, match -> first),
// Map(weight -> 1000, type -> abc, match -> third))),
// (bcd,List(Map(weight -> 182, type -> bcd, match -> second),
// Map(weight -> 150, type -> bcd, match -> fourth))),
// (aaa,List(Map(weight -> 40, type -> aaa, match -> fifth)))
// )
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.