我有一组如下:
val s = Set(Set(), Set(1, 3), Set(2), Set(1, 2), Set(2, 3),
Set(3), Set(1, 2, 3), Set(1))
我想以类似于这个的方式过滤:
s.filter(subset => subset contains !1 && 2)
其中!1 && 2
将是一些提供给我的任意布尔表达式。
我会从中回来:
Set(Set(2), Set(2, 3))
为了示例,我选择Int
,但它会是一些任意类型。
非常感谢任何帮助,谢谢。
答案 0 :(得分:1)
您的问题并不清楚“公式”是什么意思。但是,您似乎想要以某种方式参数化filter
操作。
在Scala中,我们通常通过传递代码块来实现。例如,在这个(简单的)示例中,keep
和discard
是您的两个“公式”:
def processSet[T](s: Set[Set[T]], keep: => T, discard: => T): Set[Set[T]] = {
s.filter { subset => (subset contains keep) && !(subset contains discard) }
}
然后您可以按如下方式调用该函数:
processSet(Set(Set(10, 20), Set(1, 2), Set(10, 100), Set(10, 20, 30)), 10, 30)
// returns: Set(Set(10, 20), Set(10, 100))
我不确定这是否接近你想要的东西。
答案 1 :(得分:1)
对于问题中的具体示例,您将关闭。您只需要将测试分开为1和2.另外,由于创建值s的方式,您必须使用toSet
显式转换子集:
val s = Set(Set(), Set(1, 3), Set(2), Set(1, 2), Set(2, 3),
Set(3), Set(1, 2, 3), Set(1))
s.filter{ subset =>
!(subset.toSet contains 1) && (subset.toSet contains 2)
}
如果显式转换不合适,您可以为s提供类型,如下列其中一个答案:
val s:Set[Set[Int]] = Set(Set(), Set(1, 3), Set(2), Set(1, 2), Set(2, 3),
Set(3), Set(1, 2, 3), Set(1))
s.filter{ subset =>
!(subset contains 1) && (subset contains 2)
}
只要filter
收到一个返回Boolean
值的函数(上面是anonymous function),您的方法就可以用于任意公式" 。
参数化过滤器的一种有用方法是使用curried functions:
def requirements(x: Int, y: Int)(subset: Set[Int]): Boolean = {
!(subset contains x) && (subset contains 2)
}
s.filter{ requirements(1, 2)_ }
答案 2 :(得分:0)
这对我有用(scala 2.11.4):
val s:Set[Set[Int]] = Set(Set(), Set(1, 3), Set(2), Set(1, 2), Set(2, 3),Set(3), Set(1, 2, 3), Set(1))
s.filter(subset => !subset.contains(1) && subset.contains(2))
答案 3 :(得分:0)
我使用spire' Bool来完成工作:
import spire.algebra._
import spire.implicits._
object Main {
def main(args: Array[String]): Unit = {
implicit def PredicateBooleanAlgebra[T] = new Bool[T => Boolean] {
def one: T => Boolean = _ => true
def zero: T => Boolean = _ => false
def and(a: T => Boolean, b: T => Boolean): T => Boolean = x => a(x) && b(x)
def or(a: T => Boolean, b: T => Boolean): T => Boolean = x => a(x) || b(x)
def complement(a: T => Boolean) = x => !a(x)
}
def contains1(s: Set[Int]) = s contains 1
def contains2(s: Set[Int]) = s contains 2
val s = Set(1, 2, 3).subsets.map(_.toSet).toSet
println(s.filter(~(contains1 _) & (contains2 _)))
}
}