Home > Enterprise >  How to change keys from a map in scala
How to change keys from a map in scala

Time:12-06

How to change the following keys from the map without any variables full functional

HashMap(false -> List(20, 15, 20, 17), true -> List(50, 25, 45, 21, 100, 2000, 2100))

to

HashMap("String1" -> List(20, 15, 20, 17), "String2" -> List(50, 25, 45, 21, 100, 2000, 2100))

I tried with map and was able to change the keys to the same strings but not to different ones.

CodePudding user response:

You can apply a map to all the items but focus only on the keys:

yourMap.map({ case (a, b) => (f(a), b) })

You can define f to be a function or simply a constant map e.g.:

Map(false -> "String1", true -> "String2")

Putting it all together:

object HelloWorld {
   def main(args: Array[String]) {
        val m = Map(false -> List(20, 15, 20, 17), true -> List(50, 25, 45, 21, 100, 2000, 2100))
        val f = Map(false -> "String1", true -> "String2")
        val x = m.map({ case (a, b) => (f(a), b) })
        System.out.println(x)
   }
}

Yields the expected result:

Map(String1 -> List(20, 15, 20, 17), String2 -> List(50, 25, 45, 21, 100, 2000, 2100))

If you like one-liners you can also avoid a separate map / function:

yourMap.map({
  x => x match {
    case (false, v) => ("String1", v)
    case (true, v)  => ("String2", v)
  }
})

Yet another way is to only treat the left side of the tuple:

yourMap.map({case (a, b) =>
  (a match {
     case false => "String1"
     case true  => "String2"}, b)})

And just for completeness, if your only elements really are true and false you can just do:

yourMap.map({case (a, b) => (if (a) "String2" else "String1", b)})

CodePudding user response:

Use a pattern matching anonymous function directly:

hashM
  .map {
    case (true, ints) => "String1" -> ints
    case (false, ints) => "String2" -> ints
  }

if you work with non-exhaustive pattern matching i.e. you also want to filter out safely some tuples from the collection then use collect :

hashM  
  .collect {
    case (true, ints) => "String1" -> ints
  }

you'll get here:

Map(String1 -> List(50, 25, 45, 21, 100, 2000, 2100))

It's probably the most readable solution i can think of.

  • Related