jaywalker
jaywalker

Reputation: 1146

Scala - Create a new Class on runtime based on dynamic data

I have an array of String which I will be receiving from an arbitrary function. I want to use the elements of the array to create a new class at runtime (not a new object of an existing class). Let me give you an example

val keyCounts = Array[String]

def newDomainPartioner(keyCounts : Array[Strings]) : DomainPartitioner{
    return class DomainPartitioner with Serializable {
        def getPartition(key: Any): Int = key match {

          case <first element of keyCount> => 
            1
          case <second element of keyCount> =>
            1
          case <third element of keyCount> =>  
            1
          case <forth element of keyCount> => 
            1
          case _ => 0
        }

      }
}

Is there a way to achieve the intended functionality ?

Upvotes: 0

Views: 3856

Answers (2)

user9946307
user9946307

Reputation:

val arrayStrings: Array[String] = Array("we","are","great")

def arrayCaseClass(schema:Array[String], className:String)
:String = {
  def arrayElements(element:String):String = {
    val types = element
    element match {
      case x if !x.isEmpty => s"  $element:String"
      case _ => s"  $element:$types"
    }
  }

  val fieldsName = schema.map(arrayElements).mkString(",\n  ")
  s"""
     |case class $className (
     |  $fieldsName
     |)
""".stripMargin
}


println(arrayCaseClass(arrayStrings, "ArrayCaseClass"))

Upvotes: 0

jazmit
jazmit

Reputation: 5410

You can use reflection to generate a new class at runtime, see this question for more details:

Generating a class from string and instantiating it in Scala 2.10

However, it sounds like you would be better off having a single class that encompasses the behaviour you want, and returning an instance of that class, eg:

class DomainPartitioner(keyCounts: Array[String]) with Serializable {
    def getPartition(key: Any): Int = keyCounts indexOf key match {
      case 1 => 
        1
      case 2 =>
        1
      case 3 =>  
        1
      case x if myConditionIsTrue(x) => 
        1
      case _ => 0
    }

  }

def newDomainPartioner(keyCounts : Array[Strings]) =
    new DomainPartitioner(keyCounts)

Upvotes: 3

Related Questions