3

I want to create a scala case class whose fields come form a map . And , here is the case class

 case class UserFeature(uid: String = null,
                     age: String = null,
                     marriageStatus: String = null,
                     consumptionAbility: String = null,
                     LBS: String = null,
                     interest1: String = null,
                     interest2: String = null,
                     interest3: String = null,
                     interest4: String = null,
                     interest5: String = null,
                     kw1: String = null,
                     kw2: String = null,
                     kw3: String = null,
                     topic1: String = null,
                     topic2: String = null,
                     topic3: String = null,
                     appIdInstall: String = null,
                     appIdAction: String = null,
                     ct: String = null,
                     os: String = null,
                     carrier: String = null,
                     house: String = null
                          )

suppose the map instance is

Map("uid" -> "4564131",
    "age" -> "5",
    "ct" -> "bk7755")

how can I apply the keys&values of the map to the fields&values of case class?

Alper t. Turker
  • 34,230
  • 9
  • 83
  • 115
Steve YN
  • 69
  • 1
  • 7

3 Answers3

1

You can do UserFeature(uid = map_var("uid"), age = map_var("age"), ct = map_var("ct")) assuming the variable holding Map is map_var and the keys are available

pramesh
  • 1,914
  • 1
  • 19
  • 30
  • Thank you for the answer,but , am I right in thinking the map_var("ct") may give the value of the field "marriageStatus"? – Steve YN May 17 '18 at 05:02
  • That is just extracting value. You can pass it in any position required together with other parameters or you may not use it if it's not required – pramesh May 17 '18 at 05:18
  • How the class know the value in map_var("ct") is the value of the field "ct" – Steve YN May 17 '18 at 05:46
  • That is extracting value from a key. map_var(''ct) will return "bk7755". You may not use it if not required – pramesh May 17 '18 at 05:51
  • How the class know "bk7755" is the value of the field "ct" instead of the field "marriageStatus" .And , is the compiler parse the parameter by order? – Steve YN May 17 '18 at 05:54
  • I think I'm not understanding your questions. All that happens here is, value from map is extracted and are passed to case class. I've assumed that value of 'ct' is marriageStatus. If that's not the case, you may not use it. I was only showing how to extract value from map and pass it as a parameter to case class. – pramesh May 17 '18 at 06:01
  • @pms The problem with your answer is that you have assigned `map_var("ct")` to the `marriageStatus` field, when it should be in the `ct` field. – Tim May 17 '18 at 07:02
1

It is not a good idea to use null to represent missing string values. Use Option[String] instead.

case class UserFeature(uid: Option[String] = None,
                       age: Option[String] = None,
                       marriageStatus: Option[String] = None,
                       ...

Once you have done that, you can use get on the map to retrieve the value.

UserFeature(map.get("uid"), map.get("age"), map.get("marriageStatus") ...)

Values that are present in the map will be Some(value) and missing values will be None. The Option class has lots of useful methods for processing optional values in a safe way.

Tim
  • 26,753
  • 2
  • 16
  • 29
  • Thank you for the wonderful explanation on Option[String],do you have github or something I can fellow? – Steve YN May 17 '18 at 07:43
  • @SteveYN Happy to help, but I don't have a github presence or anything similar. – Tim May 17 '18 at 08:37
1

Synthesizing the other two answers, I would convert all the Strings in UserFeature that you're defaulting to null (which you should basically never use in Scala unless interacting with poorly-written Java code requires it, and even then use it as little as possible) to Option[String]. I leave that search-and-replace out of the answer.

Then you can do:

object UserFeature {
  def apply(map: Map[String, String]): UserFeature =
    UserFeature(map.get("uid"), map.get("age") ...)
}

Which lets you use:

val someMap: Map[String, String] = ...
val userFeature = UserFeature(someMap)

With the change to Option[String], there will be some other changes that need to be made in your codebase. https://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html is a good tutorial for how to deal with Option.

Levi Ramsey
  • 18,884
  • 1
  • 16
  • 30