简体   繁体   中英

How can I replace my multiple exists in Scala?

I have this block of code that looks determines the service charge based on the existence of an item of a chosen category:

def bill(purchasedItems: List[String]): BigDecimal = {
    def totalCost: BigDecimal = purchasedItems.foldLeft(BigDecimal(0))((tot, p) => tot + menu(p).price)

    def serviceChargeRate: BigDecimal = if (purchasedItems.exists(name => menu(name).serviceChargeCategory == PremiumItem)) 1.2
    else if (purchasedItems.exists(name => menu(name).serviceChargeCategory == Food)) 1.1
    else 1.0

    totalCost * serviceChargeRate
  }

I tried replacing this with collectFirst but this will match the first item rather than use the priority order to ensure the highest service charge is used.

 def bill(purchasedItems: List[String]): BigDecimal = {
    def totalCost: BigDecimal = purchasedItems.foldLeft(BigDecimal(0))((tot, p) => tot + menu(p).price)

    def serviceChargeRate: Option[BigDecimal] = purchasedItems.map(menu(_).serviceChargeCategory) collectFirst {
      case PremiumItem => BigDecimal("1.2")
      case Food => BigDecimal("1.1")
    }

    totalCost * serviceChargeRate.getOrElse(BigDecimal("1.0"))
  }

Is there a nicer, more functional way to do this in Scala or do I have to accept the if/else block ?

Thanks

Ben

My suggestion would run along these lines:

def bill(purchasedItems: List[String]): BigDecimal = {
  val  totalCost: BigDecimal = purchasedItems.foldLeft(BigDecimal(0))((tot, p) => tot + menu(p).price)
  val serviceRate: BigDecimal = purchasedItems.map { item ⇒ menu(item).serviceChargeCategory match {
    case "PremiumItem" ⇒ 1.2
    case "Food" ⇒ 1.1
    case _ ⇒ 1.0
}}.max

  totalCost * serviceChargeRate
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM