Scala:作为方法参数的动态选择条件

Scala:作为方法参数的动态选择条件,scala,pattern-matching,anonymous-types,Scala,Pattern Matching,Anonymous Types,我的意图是在Scala中创建一个函数,它接受某种动态查询(类似于模式匹配中的case表达式),并在列表中返回匹配实例。假设列表由案例类Person的实例组成,这些实例几乎没有不同类型的属性。函数应该能够接受某些字段的值的动态组合,并返回匹配的Persons。我特别寻找一个干净的解决方案。使用此函数的一种可能方法是传递匿名类型的对象作为查询(“模式”): def find(?):List={?} val matches=find(新的{val name=“name”;val gender=gend

我的意图是在Scala中创建一个函数,它接受某种动态查询(类似于模式匹配中的
case
表达式),并在
列表中返回匹配实例。假设列表由
案例类Person
的实例组成,这些实例几乎没有不同类型的属性。函数应该能够接受某些字段的值的动态组合,并返回匹配的
Person
s。我特别寻找一个干净的解决方案。使用此函数的一种可能方法是传递匿名类型的对象作为查询(“模式”):

def find(?):List={?}
val matches=find(新的{val name=“name”;val gender=gender.MALE})

理想情况下,我想开发一种干净的传递条件的方式,而不是具体的价值观,但这不是必要的。因为我正在学习Scala,所以我不知道实现这种东西的所有技术。在C#中,我使用了匿名类型(类似于上面的第二行代码)和
动态
参数来实现类似的功能。什么是Scala中干净优雅的解决方案?

我不确定这是否是您想要的,但让我们这样试试:

首先,我们将
Person
定义为
case类Person(name:String,gender:gender.Value)
其中
gender
是已经定义的枚举

然后,我们创建一个
查询
案例类,该类具有相同的字段,但作为默认为
的选项,以及一个将查询与人进行比较的方法:

case class Query(name: Option[String] = None, 
                 gender: Option[Gender.Value] = None){

  def ===(person: Person) = check(person.name, name) && 
                            check(person.gender, gender)

  private def check[T](field: T, q: Option[T]) = field == q.getOrElse(field)
}
不幸的是,在这个解决方案中,
==
必须为每个字段分别调用
check
。现在就这样吧。也许这就足够了(例如,因为字段列表不会更改)

请注意,
check
如果查询的选项为
None
,则返回
true
,因此您不必通过查询的所有字段:

val q = Query(name = Some("Ann")) // the gender is not important
q === Person("Ann", Gender.FEMALE) // returns true
最后是
find
方法:

def find(people: List[Person], query: Query) = people.filter(query === _)

匿名谓词不够清晰解决方案
xs.find(person=>person.name==“name”&&person.gender==gender.MALE)
?如果条件是静态的,它们是。例如,在运行之前,不确定是否应检查名称。您所描述的内容类似于ScalaTest的matchers,您可以编写类似于
person-should have('name(“name”),'gender(gender.MALE))
。当匹配器用于断言时,您可能能够根据自己的目的调整实现。查看“使用Have检查任意属性”:
def find(people: List[Person], query: Query) = people.filter(query === _)