Card with specific keys

As for maps in Scala, if ms - (k, 1, m) returns a map containing all ms maps except for any comparison with the given keys x, 1 and m.

Then, which operator will return the mapping of all mappings ms with only given keys, x, 1 and m. those. I'm looking for a subset of ms, where only k, 1 and m are keys.

This works, but it's terrible:

 scala> val originalMap = Map("age" -> "20", "name" -> "jack", "hobby" -> "jumping") ms: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20, name -> jack, hobby -> jumping) scala> val interestingKeys = List("name", "hobby") interesting: List[java.lang.String] = List(name, hobby) scala> val notInterestingMap = originalMap -- interestingKeys notInterestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20) scala> val interestingMap = originalMap -- notInterestingMap.keySet interestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping) 
+6
source share
3 answers

Since filterKeys filters are based on an arbitrary predicate, it must consider every key on the map. This may be good or not, depending on how big the map is, etc., but it is definitely not necessary for the operation described. I would use something like the following:

 interestingKeys.flatMap(k => originalMap.get(k).map((k, _))).toMap 

This will be O(n) or O(n log m) depending on your map implementation (where n is the size of interestingKeys and m is the size of the map) instead of O(m log n) or O(mn) .

If you really need your ~ operator, you can use the pimp-my-library template:

 class RichMap[A, B](m: Map[A, B]) { def ~(ks: A*) = ks.flatMap(k => m.get(k).map((k, _))).toMap } implicit def enrichMap[A, B](m: Map[A, B]) = new RichMap(m) 

Now originalMap ~ ("name", "hobby") returns Map(name -> jack, hobby -> jumping) , as you would expect.

+7
source

filterKeys can help:

 scala> originalMap.filterKeys(interestingKeys.contains) res0: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping) 
+7
source

I think the source code is not so bad, and it can be easily converted to single-line, working on sets of keys:

 val interestingMap = originalMap -- (originalMap.keySet -- interestingKeys) 

I find this quite readable.

+1
source

Source: https://habr.com/ru/post/908508/


All Articles