Scala 如何避免此生成器中的任何可变内容?
我有一个简单的Scala类,如下所示:Scala 如何避免此生成器中的任何可变内容?,scala,functional-programming,immutability,Scala,Functional Programming,Immutability,我有一个简单的Scala类,如下所示: class FiltersBuilder { def build(filter: CommandFilter) = { val result = collection.mutable.Map[String, String]() if (filter.activity.isDefined) { result += ("activity" -> """ some specific expression """)
class FiltersBuilder {
def build(filter: CommandFilter) = {
val result = collection.mutable.Map[String, String]()
if (filter.activity.isDefined) {
result += ("activity" -> """ some specific expression """)
} // I well know that manipulating option like this is not recommanded,
//it's just for the simplicity of the example
if (filter.gender.isDefined) {
result += ("gender" -> """ some specific expression """)
}
result.toMap //in order to return an immutable Map
}
}
使用该类以便:
case class CommandFilter(activity: Option[String] = None, gender: Option[String] = None)
结果
内容取决于所选筛选器及其关联和硬编码表达式(字符串
)的性质
是否有方法通过删除
mutable.Map
)的“可变性”来转换此代码段 我刚刚通过这个解决方案实现了这一点:
class FiltersBuilder(commandFilter: CommandFilter) {
def build = {
val result = Map[String, String]()
buildGenderFilter(buildActivityFilter(result))
}
private def buildActivityFilter(expressions: Map[String, String]) =
commandFilter.activity.fold(expressions)(activity => result + ("activity" -> """ expression regarding activity """))
private def buildGenderFilter(expressions: Map[String, String]) =
commandFilter.gender.fold(expressions)(gender => result + ("gender" -> """ expression regarding gender """))
}
有更好的方法吗?我刚刚用这个解决方案实现了:
class FiltersBuilder(commandFilter: CommandFilter) {
def build = {
val result = Map[String, String]()
buildGenderFilter(buildActivityFilter(result))
}
private def buildActivityFilter(expressions: Map[String, String]) =
commandFilter.activity.fold(expressions)(activity => result + ("activity" -> """ expression regarding activity """))
private def buildGenderFilter(expressions: Map[String, String]) =
commandFilter.gender.fold(expressions)(gender => result + ("gender" -> """ expression regarding gender """))
}
有更好的方法吗?因为您的
地图中最多有2个元素
:
val activity = filter.activity.map(_ => Map("activity" -> "xx"))
val gender = filter.gender.map(_ => Map("gender" -> "xx"))
val empty = Map[String, String]()
activity.getOrElse(empty) ++ gender.getOrElse(empty)
由于
地图中最多有2个元素
:
val activity = filter.activity.map(_ => Map("activity" -> "xx"))
val gender = filter.gender.map(_ => Map("gender" -> "xx"))
val empty = Map[String, String]()
activity.getOrElse(empty) ++ gender.getOrElse(empty)
将结果添加到
Seq
时,将每个过滤器字段映射到一个元组,然后使用flatten
过滤掉None
s,最后使用toMap
将Seq
元组转换为Map
要添加更多要筛选的字段,只需在
Seq
def build(filter: CommandFilter) = {
// map each filter filed to the proper tuple
// as they are options, map will transform just the Some and let the None as None
val result = Seq(
filter.activity.map(value => "activity" -> s""" some specific expression using $value """),
filter.gender.map(value => "gender" -> s""" some specific expression using $value """)
).flatten // flatten will filter out all the Nones
result.toMap // transform list of tuple to a map
}
希望有帮助。加斯顿。将结果添加到
Seq
时,将每个过滤字段映射到一个元组,然后使用flatten
过滤掉None
s,最后使用toMap将元组的Seq
转换为Map
要添加更多要筛选的字段,只需在Seq
def build(filter: CommandFilter) = {
// map each filter filed to the proper tuple
// as they are options, map will transform just the Some and let the None as None
val result = Seq(
filter.activity.map(value => "activity" -> s""" some specific expression using $value """),
filter.gender.map(value => "gender" -> s""" some specific expression using $value """)
).flatten // flatten will filter out all the Nones
result.toMap // transform list of tuple to a map
}
希望有帮助。
加斯顿