我有Map[String, Int]
val labelMap: mutable.HashMap[String, Int] = sparse0.sparseOperationCountRowsByTarget()
我想在一个语句中过滤该地图。过滤器可以按String
或Int
最粗略的形式看起来像这样:
val labelMapFiltered = labelMap.filter(label => label._1.startsWith("REL") || label._2 < 400)
现在我已经有了String和Int函数的通用实用程序谓词。字符串谓词是:
object StringPredicates
{
def stringEquals(required:String)(input:String) = input == required
def stringStartsWith(required:String)(input:String) = input.startsWith(required)
def stringContains(required:String)(input:String) = input.contains(required)
def and(predicates:Seq[String => Boolean])(input:String) = predicates.forall(predicate => predicate(input))
def or(predicates:Seq[String => Boolean])(input:String) = predicates.exists(predicate => predicate(input))
}
Int谓词与上面的模式相同。
这允许使用以下过滤器:
val sw1=stringContains("#")
val sw2=stringStartsWith("REL")
val sw3=intGT(400)
val labelMapFiltered = labelMap.filter( label =>sw1(label._1) || sw2(label._1) || sw3(label._2) )
我想将谓词传递给函数(作为Seq,我假设),然后过滤。 所以我正在寻找类似的东西:
val labelMapFiltered = labelMap.filter( myFunction(myPredSeq))
我可以使用已有的谓词吗?在Tuple2[String,Int]
中编写与此函数中特定Map匹配的谓词似乎过于具体。然后,我必须为我想要过滤的每种类型的地图编写谓词。
答案 0 :(得分:3)
您可以使用compose
方法将谓词转换为接受适当的类型,例如:
val sw1: (String, Int) => Boolean = stringContains("#").compose(kv: (String, Int) => kv._1)
甚至可以做同样的事情,但映射你的谓词:
val predsOfTuples1 = predsOfStrings.map(_.compose(kv: (String, Int) => kv._1)))
val predsOfTuples2 = predsOfInts.map(_.compose(kv: (String, Int) => kv._2))
val preds = predsOfTuples1 ++ predsOfTuples2
您需要做的最后一件事是将and
和or
方法设为通用的,这样您就可以在元组的谓词上使用它们:
def and[A](predicates:Seq[A => Boolean])(input:A) = predicates.forall(predicate => predicate(input))
def or[A](predicates:Seq[A => Boolean])(input:A) = predicates.exists(predicate => predicate(input))
答案 1 :(得分:0)
让我们简化输入并考虑一个简单的Int
s列表:
List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
您可以将所有谓词放在Stream
中(以便对它们进行懒惰评估,而不必评估所有谓词):
val predicates = Stream((n: Int) => n == 0, (n: Int) => n % 2 == 1, (n: Int) => n >= 8)
规则是如果数字为0,奇数或更大或等于8,则将保留数字。
现在我们要求通过查看我们的集合中是否至少有一个返回true
的谓词来过滤:
list.filter(n => predicates.exists(p => p(n)))
输出是一个至少遵守其中一条规则的数字列表:
List(0, 1, 3, 5, 7, 8, 9)