Добавление элементов на карту после проверки условия scala

#scala #apache-spark

#scala #apache-spark

Вопрос:

У меня есть класс case

 case class DDD(abc: String, v1: String, v2: String)
  

и у меня есть кортеж, основанный на DDD (схеме). Итак, представьте это

 val sample1 = DDD("a1", "v0001", "v0002")
  

и затем я создаю карту из значений этого кортежа следующим образом

 val tMap = Map("col_name" -> sample1.abc, "col_old" -> sample1.v1, "col_new" -> sample1.v2)
  

Но могут быть случаи, когда мои значения v1 или v2 в моих кортежах могут быть пустыми / null / empty, и если значение отсутствует, я не хочу добавлять эту пару ключ-значение на мою карту, поэтому
Например

 If 
val sample2 = DDD("a1", "null", "v0002")

Then
val tMap = Map("col_name" -> sample1.abc, "col_new" -> sample1.v2)
  

Я могу достичь этого, просто используя условие if, как показано ниже

 val sample2 = DDD("a1", "null", "v0002")

val tMap = Map("col_old" -> (if(sample2.v1 != "null") sample2.v1),
"col_new" -> (if(sample2.v2 != "null") sample2.v2
"abc" -> (if(sample2.abc != "null") sample2.abc
) 
  

Но нужно сделать и понять, как я могу достичь этого более чистым функциональным способом. ???

Спасибо

Комментарии:

1. Подсказка: вы можете определить объект класса case DDD, здесь вы пишете, что определяете свои вспомогательные конструкторы на основе ваших конкретных условий

Ответ №1:

Как насчет чего-то подобного?

 case class DDD(abc: String, v1: String, v2: String)

val sample1 = DDD("a1", "null", "v0002")

val mapKeys = List("col_name", "col_old", "col_new")

val tMap =
  (mapKeys.toIterator zip sample1.productIterator).collect {
    case (k, v: String) if (v != "null")=> k -> v
  }.toMap
// tMap: Map[String, String] = Map(col_name -> a1, col_new -> v0002)
  

Комментарии:

1. не хочу устанавливать mapKeys отдельно

2. @AJm В чем проблема с наличием ключей в виде внешнего списка?

3. У нас есть определенные стандарты кода, которым нужно следовать, это не будет принято

4. @AJm Какой стандарт кода запрещает это? По какой конкретной причине? — Кроме того, если вы не можете иметь ключи в виде какой-либо коллекции, не было бы никакого другого решения, кроме проверки условия и добавления значений одно за другим.

Ответ №2:

Почему бы вам не создать пользовательский метод unapply для этого класса case?

По умолчанию Scala создает одноэлементный объект, в котором указаны методы apply и unapply. Итак, вам следует создать еще один.

 object DDD {
   def unapply(arg: DDD): Map[String, String] = {
      def mapIfNotNull(key:String, value:String):Option[(String, String)] = if (value == "null") None else Some(key -> value)
      Seq(
        mapIfNotNull("col_name", arg.abc),
        mapIfNotNull("col_old", arg.v1),
        mapIfNotNull("col_new", arg.v2)
      ).flatten.toMap
    } 
}
  

Затем вы можете использовать этот синглтон позже, чтобы отменить применение экземпляра класса case.

 DDD.unapply(sample1)
  

Я думаю, что этот способ более чистый