如何用不可变集合以函数式方式构建条件化披萨配料列表?
用Scala不可变集合实现条件化披萨配料的函数式写法
当然有啦!用Scala的不可变集合来实现这种条件化添加配料的需求,完全可以写出简洁又符合函数式风格的代码,还能避免可变集合带来的副作用问题。
你一开始想到的Option思路非常靠谱,我来给你完善并补充几种常用的实现方式:
方法一:结合Option与flatten
这是对你思路的直接延伸,把每个条件对应的配料包装成Some或None,最后通过flatten过滤掉空值:
val ingredients = List("tomatoes", "cheese") ++ List( if (!isVegetarian()) Some("Pepperoni") else None, if (shouldBeSpicy()) Some("Jalapeno") else None ).flatten
原理很简单:List(Some("Pepperoni"), None)经过flatten后会变成List("Pepperoni"),自动忽略所有None元素,完美实现条件添加。
方法二:用collect过滤符合条件的配料
如果把条件和配料做成元组,collect可以帮我们精准提取满足条件的元素,写法也很直观:
val ingredients = List("tomatoes", "cheese") ++ List( (!isVegetarian(), "Pepperoni"), (shouldBeSpicy(), "Jalapeno") ).collect { case (isNeeded, ingredient) if isNeeded => ingredient }
这里的模式匹配只会保留第一个元素为true的元组对应的配料,后续如果要加更多条件,扩展起来也很方便。
方法三:直接拼接条件化的列表
这种方式最直白,每个条件直接返回对应的单元素列表或者空列表Nil,再用++拼接:
val ingredients = List("tomatoes", "cheese") ++ (if (!isVegetarian()) List("Pepperoni") else Nil) ++ (if (shouldBeSpicy()) List("Jalapeno") else Nil)
Nil和任何列表拼接都不会改变原列表的内容,这种写法可读性拉满,哪怕是刚接触Scala的新手也能一眼看懂逻辑。
这几种方式都是纯函数式的,完全依赖不可变集合,没有任何修改原集合的副作用,而且代码整洁易维护,比可变集合的写法更符合Scala的设计哲学。
内容的提问来源于stack exchange,提问作者Krzysztof Atłasik
相关产品推荐
相关产品推荐

