Scala过滤别名集的所有元素

Posted

技术标签:

【中文标题】Scala过滤别名集的所有元素【英文标题】:Scala filter on all elements of an alias Set 【发布时间】:2018-03-17 19:24:16 【问题描述】:

这是问题。

我有这个类型集:

type Set = Int => Boolean

我可以这样使用:

val belowNegFive: Set = (i) => i < -5
belowNegFive(10)

我的意思是返回一个布尔值,具体取决于元素 10 是否属于 -5 以下的数字集。

    我有这段代码,它返回s 的子集,p 持有该子集。
def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)

Q1:我怎么知道 p(e) 告诉我 int e 满足谓词 p?

    我有这个 fc,它返回 s 内的所有有界整数是否满足 p
def contains(s: Set, elem: Int): Boolean = s(elem)

val bound = 1000    
def forall(s: Set, p: Int => Boolean): Boolean = 
def iter(a: Int): Boolean = 
  if (a > bound) true
  else if (contains(s, a) && !p(a)) false
  else iter(a+1)
  
iter(-bound)

Q2:为什么所有的 a > 边界默认都简单地满足谓词的条件?或者 true 只是一个停止条件?我不确定为什么这个 fc 不返回无限循环。只是一个无限的布尔值列表,最后一个布尔值对于所有 a > 边界都是“真、真、真……”。

Q3:我看不出它在哪个点使用 && 在结果布尔值之间表示是,s 内的所有有界整数都满足 p

谢谢

【问题讨论】:

第一部分没看懂。您能否详细说明您想在第一季度提出的问题? pInt=&gt;BooleaneInt 因此 p(e)Boolean。所以e满足p如果p(e)返回true 我可能回答了你自己的问题。我注意到谓词 p: Int => Boolean 的处理方式与类型 Set = Int => Boolean 相同。如果我们将 s 定义为 Set,则方法 s(e: Int) 指示 e 是否属于 Set s。所以 p(e: Int) 应该有相同的结果。 如果 a &gt; bound 则您已经遍历了 a 的所有可能值(在边界内)。如果您现在还没有找到false,那么就没有。如果没有false,那么它必须是true 如果s 确实not 包含a,那么我们不关心谓词p(a) 是否成立。因此,如果a 不是 s 的成员,则将跳过谓词测试。只有当a s 的成员时,我们才会测试谓词p(a) 【参考方案1】:

对于第一季度: p 是一个接受整数并返回布尔值的函数。我的谓词可能类似于,number 应该小于 -10。我的设置可以,应该小于-5。 filter 将返回两者都持有的自定义集。

  type Set = Int => Boolean
  val belowNegFive: Set = (i) => i < -5

  def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)
  val predicate: Int => Boolean = (num) => num < -10    

  val myset = filter(belowNegFive, predicate)
  myset(0) #=> false
  myset(-1) #=> false
  myset(-10) #=> false
  myset(-11) #=> true

第二季度:

def contains(s: Set, elem: Int): Boolean = s(elem)

val bound = 1000    
def forall(s: Set, p: Int => Boolean): Boolean = 
def iter(a: Int): Boolean = 
  if (a > bound) true
  else if (contains(s, a) && !p(a)) false
  else iter(a+1)
  
iter(-bound)

这是一个停止条件。 forall 规定,如果对于所有整数 b/w -1000 到 1000(绑定),如果 set 包含整数并且谓词成立,则为真。如您所见,在最后一行中,检查从 -1000 (iter(-bound)) 开始。

Q3:集合和谓词的真值表是什么样的?

set  | predicate | should continue checking?  
____________________________________________
true | true      | yes
false| true      | yes 
true | false     | no 
false| false     | yes

如您所见,它应该返回false 的唯一条件是第三个条件,即else if 条件。对于所有其他人,它会继续检查下一个整数是否存在于集合和谓词中。

【讨论】:

你好。 Q1:我明白了。关于它的另一个问题。我有代码: type Set = Int => Boolean def fc(s: Set) = (i: Int) => s(i) 编译器如何知道 s(i) 是谁?我没有定义它。我只有这 2 行代码。 对于 Q2、Q3:我仍然不确定停止条件。我了解真值表。但是 fc "iter" 接收 -100 到 100 之间的所有数字作为输入(-bound 和 bound)。所以一个整数列表。但它只返回一个布尔值。对我来说,我认为它返回由 if 条件产生的最后一个布尔值。 (“Iter”是一个递归 fc。但是使用其他递归 fc(例如阶乘)要容易得多。从代码中可以明显看出,所有先前的结果都相互相乘,直到达到停止条件 n == 1。这里, 停止条件为 > 界限并不明显。) 我看到数字a可以继续增加到101、102...(为什么不呢?)。在这种情况下,“a > bound”会给出无限的真布尔值(也许我错过了这些递归 fc 背后的一般原则) a &gt; bound 只是这个函数中的一个停止条件,就像在阶乘函数中你在 n == 1 处停止一样。我认为你也可以用 a == bound + 1 代替 a &gt; bound这将消除与无限集的一些混淆。我同意这不是最好的迭代函数。其他递归函数的代码有不同的目标,它们将最后的结果带入新的值,它们遵循尾递归。这只是一个没有 for/while 循环的迭代。 对于def fc(s: Set) = (i: Int) =&gt; s(i)s 是一个 Set,这里定义为一个接受整数并返回布尔值的函数。在这种情况下,s(i) 自然知道它的返回类型为布尔值。

以上是关于Scala过滤别名集的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

django 查询所有与相关集的过滤?

scala过滤操作过滤CSV文件

如何使用基本页面的别名作为上下文过滤器

2021年大数据常用语言Scala(二十四):函数式编程 过滤  filter

如何在 django 中过滤查询集的多对多

关于ManyToMany过滤和组合查询集的非常奇怪的行为