是否有一个快捷方式来过滤Map,只保留给定Set中包含密钥的条目?
这是一些示例代码
scala> val map = Map("1"->1, "2"->2, "3"->3)
map: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3)
scala> map.filterKeys(Set("1","2").contains)
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2)
我正在寻找比这短的东西.
oxb*_*kes 50
你可以利用a Set[A]是谓词的事实; 即A => Boolean
map filterKeys set
这是在工作:
scala> val map = Map("1" -> 1, "2" -> 2, "3" -> 3)
map: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3)
scala> val set = Set("1", "2")
set: scala.collection.immutable.Set[java.lang.String] = Set(1, 2)
scala> map filterKeys set
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2)
或者如果您愿意:
scala> map filterKeys Set("1", "2")
res1: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2)
实际上,有一个谓词包装器非常有用.像这样:
scala> class PredicateW[A](self: A => Boolean) {
   | def and(other: A => Boolean): A => Boolean = a => self(a) && other(a)
   | def or(other: A => Boolean): A => Boolean = a => self(a) || other(a)
   | def unary_! : A => Boolean = a => !self(a)
   | }
defined class PredicateW
并隐式转换:
scala> implicit def Predicate_Is_PredicateW[A](p: A => Boolean) = new PredicateW(p)
Predicate_Is_PredicateW: [A](p: A => Boolean)PredicateW[A]
然后你可以使用它:
scala> map filterKeys (Set("1", "2") and Set("2", "3"))
res2: scala.collection.immutable.Map[java.lang.String,Int] = Map(2 -> 2)
scala> map filterKeys (Set("1", "2") or Set("2", "3"))
res3: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3)
scala> map filterKeys !Set("2", "3")
res4: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1)
这可以扩展到xor,nand等等等等,如果你有象征性的Unicode可以为惊人的可读的代码:
val mustReport = trades filter (uncoveredShort ? exceedsDollarMax)
val european = { 
  val Europe = (_ : Market).exchange.country.region == Region.EU
  trades filter (_.market ?: Europe)
}
一个切向的提示,如果您要遵循PredicateW@oxbow_lakes的回答中的想法:
在函数式编程中,我们的目标是更通用和可组合的抽象,而不是定义ad hoc函数.对于这种特殊情况,Applicative适合该法案.
Set它们本身就是函数,而Applicative实例[B]Function1[A, B]让我们将函数提升到上下文.换句话说,您可以将类型(Boolean, Boolean) => Boolean(例如||,&&等)的功能提升到(A => Boolean, A => Boolean) => (A => Boolean).(在这里你可以找到关于这种提升概念的很好的解释.)
然而,数据结构Set本身具有Applicative可用的实例,这将在[B]Applicative[A => B]实例上受到青睐.为了防止这种情况,我们必须明确告诉编译器将给定集视为函数.我们为此定义了以下内容:
scala> implicit def setAsFunction[A](set: Set[A]) = new {
     |   def f: A => Boolean = set
     | }
setAsFunction: [A](set: Set[A])java.lang.Object{def f: A => Boolean}
scala> Set(3, 4, 2).f
res144: Int => Boolean = Set(3, 4, 2)
现在Applicative使用这个好处.
scala> val map = Map("1" -> 1, "2" -> 2, "3" -> 3)
map: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3)
scala> map filterKeys ((Set("1", "2").f |@| Set("2", "3").f)(_ && _))
res150: scala.collection.immutable.Map[java.lang.String,Int] = Map(2 -> 2)
scala> map filterKeys ((Set("1", "2").f |@| Set("2", "3").f)(_ || _))
res151: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3)
scala> map filterKeys (Set("2", "3").f map (!_))
res152: scala.collection.immutable.Map[java.lang.String,Int] = Map(1 -> 1)
注意:以上所有都需要Scalaz.
抱歉,不能直接回答您的问题,但如果您知道要删除的密钥(而不是您要保留的密钥),则可以执行以下操作:
map -- Set("3")
| 归档时间: | 
 | 
| 查看次数: | 15977 次 | 
| 最近记录: |