首页 > 解决方案 > 有条件地构建避免突变的列表

问题描述

假设我想有条件地建立比萨的成分列表:

val ingredients = scala.collection.mutable.ArrayBuffer("tomatoes", "cheese")

if (!isVegetarian()) {
   ingredients += "Pepperoni"  
}

if (shouldBeSpicy()) {
   ingredients += "Jalapeno"
}

//etc

有没有使用不可变集合构建这个数组的功能性方法?

我想过:

val ingredients = List("tomatoes", "cheese") ++ List(
    if (!isVegetarian()) Some("Pepperoni") else None,
    if (shouldBeSpicy()) Some("Jalapeno") else None
).flatten

但有更好的方法吗?

标签: scalacollections

解决方案


这是另一种更接近@Antot但恕我直言更简单的可能方式。

您的原始代码中不清楚的是来自何处isVegetarian以及shouldBeSpicy实际来自何处。在这里,我假设有一个PizzaConf如下的类来提供这些配置设置

case class PizzaConf(isVegetarian: Boolean, shouldBeSpicy: Boolean)

假设这一点,我认为最简单的方法是使用一种allIngredients类型List[(String, Function1[PizzaConf, Boolean])],即存储成分和功能以检查其相应可用性的类型。鉴于这buildIngredients变得微不足道:

val allIngredients: List[(String, Function1[PizzaConf, Boolean])] = List(
  ("Pepperoni", conf => conf.isVegetarian),
  ("Jalapeno", conf => conf.shouldBeSpicy)
)

def buildIngredients(pizzaConf: PizzaConf): List[String] = {
  allIngredients
    .filter(_._2(pizzaConf))
    .map(_._1)
}

或者您可以合并filtermap使用collect如下:

def buildIngredients(pizzaConf: PizzaConf): List[String] = 
  allIngredients.collect({ case (ing, cond) if cond(pizzaConf) => ing })

推荐阅读