2017-08-09 4 views
0

私は次のケースのクラスがあります。私もはオプションにMapオブジェクトをマッピングする[反復処理可能[行]オプションを導出する[一覧[アドレス]]

case class Address (
        val addressLine1: String, 
        val addressLine2: String, 
        val city: String, 
        val provinceCode: String, 
        val country: String, 
        val addressTypeDesc: String) 

case class ClientData(
         val title: String, 
         val firstName: String, 
         val lastName: String, 
         val addrList: Option[List[Address]] 
        ) 

import org.apache.spark.sql.Row 

object ClientBuilder { 

    def build(client: Row, addr: Option[Iterable[Row]], addrType: Map[String, String]): ClientData = { 

    // The object validates that the field “ClientTitle” is empty or one of the following values only: 
    // "Mr.", "Ms.", "Mrs." - Otherwise the build will throw an IllegalArgumentException 
    val title: String = 
    client.getAs[String]("Title") match { 
     case "Mr." => "Mr." 
     case "Ms." => "Ms." 
     case "Mrs." => "Mrs." 
     case "" => "" 
     case _ => throwException("Client Title is not as expected") 
    } 
    val firstName: String = client.getAs[String]("FirstName") 
    val lastName: String = client.getAs[String]("LastName") 

    val addrList: Option[List[Address]] = // having some problem figuring this part out 

     ClientData(title, firstName, lastName, addrList) 
    } 

    def throwException(exceptionReason: String) = { 
    throw new IllegalArgumentException(s"Exception thrown due to: ${exceptionReason}") 
    } 
} 

addr: Option[Iterable[Row]]

:次のオブジェクトを持っています

は次の列があります。次のように

AddressID,AddressLine1,AddressLine2,City,ProvinceName,ProvinceCode,Country,ClientID,AddressTypeCode 

addrType: Map[String, String])

は次のとおりです。

Map(1 -> "Billing", 2 -> "Home", 3 -> "Main Office", 4 -> "Primary", 5 -> "Shipping", 6 -> "Archive") 

私はaddrAddressTypeCodeaddrTypeキーにaddrType: Map[String, String])addr: Option[Iterable[Row]]に参加したいと思いますaddressTypeDescを取得し、タイプAddressのリストを作成します。

答えて

0

[OK]をので、私はOption[Iterable[Row]]を反復処理し、Option[Iterable[Row]]内の各クライアントのアドレスのリストにADDRTYPEをマップするOption.get()メソッドを使用して、それを解決するために管理しました。ここで私はこれを達成した方法です:

object ClientBuilder { 

    def build(client: Row, addr: Option[Iterable[Row]], addrType: Map[String, String]): ClientData = { 

    // The object validates that the field “ClientTitle” is empty or one of the following values only: 
    // "Mr.", "Ms.", "Mrs." - Otherwise the build will throw an IllegalArgumentException 
    val title: String = 
    client.getAs[String]("Title") match { 
     case "Mr." => "Mr." 
     case "Ms." => "Ms." 
     case "Mrs." => "Mrs." 
     case "" => "" 
     case _ => throw new IllegalArgumentException(s"Exception thrown due to: Invalid Title. Title must be: Mr., Ms., Mrs., or empty.") 
    } 
    val firstName: String = client.getAs[String]("FirstName") 
    val lastName: String = client.getAs[String]("LastName") 

    // iterate through the Option[Iterable[Row]] and write each row to Option[Iterable[Address]]. 
    val addrList = Option(
     for(address <- addr.getOrElse(List()).toList) yield { 
     Address(
      address.getAs("AddressLine1"), 
      address.getAs("AddressLine2"), 
      address.getAs("City"), 
      address.getAs("ProvinceCode"), 
      address.getAs("Country"), 
      // using the getAs() method of the addrType Map object map get the AddressTypeDescription 
      addrType.getOrElse(address.getAs("AddressTypeCode").toString,"No such address type") 
     ) 
     } 
    ) 
    ClientData(title, firstName, lastName, addrList) 
    } 
} 

しかし、これは最も効率的なアプローチではないかもしれません。私の同僚の一人と話した後、彼らは次のアプローチを使用することを提案した。

object ClientBuilder { 
    def build(client: Row, addr: Option[Iterable[Row]], addrType: Map[String,String]): ClientData = { 
    val addrList: Option[List[Address]] = 
     if (addr.isEmpty) None 
     else 
     Some(
      addr.get.map((addrRow: Row) => 
      Address(
       addrRow.getAs[String]("AddressLine1") 
       , addrRow.getAs[String]("AddressLine2") 
       , addrRow.getAs[String]("City") 
       , addrRow.getAs[String]("ProvinceCode") 
       , addrRow.getAs[String]("Country") 
       , addrType.get(addrRow.getAs[String]("AddressTypeCode")).getOrElse("") 
      ) 
     ).toList 
     ) 

    val firstName: String = DFAsist.safeGeteString(client, "FirstName").getOrElse("") 
    val lastName: String = DFAsist.safeGeteString(client, "LastName").getOrElse("") 
    val title: String = DFAsist.safeGeteString(client, "Title") match { 
     case None => "" 
     case Some(s) if List("Mr.", "Ms.", "Mrs.").contains(s) => s 
     case _ => throw new IllegalArgumentException("Title is wrong!!!") 
    } 


    ClientData(title,firstName,lastName, addrList) 
    } 
関連する問題