【问题标题】:Scala return boolean with if elseScala用if else返回布尔值
【发布时间】:2016-03-18 10:06:08
【问题描述】:

所以我必须遵循以下场景:

 def check(): Boolean = {
    for ((digit1,digit2,digit3) <- SetOfDigits){
      if ((1,2,5) == (digit1,digit2,digit3))
        true
      else
        false
}
  }

val SetOfDigits = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5))

现在的问题是该函数必须返回一个布尔值,但它总是告诉我这里的返回类型是Unit? 该函数应该遍历SetOfDigits,如果它找到类似(1,2,5)的东西,它应该返回true,否则返回false? 有没有人回答这个问题以及我必须做些什么才能让它工作?

【问题讨论】:

    标签: scala function set boolean


    【解决方案1】:

    我不同意V先生的解决方案,我宁愿建议你改变你的实现,这似乎是一种非常Javish的处理方式:

    scala> val SetOfDigits = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5))
    SetOfDigits: scala.collection.immutable.Set[(Int, Int, Int)] = Set((0,2,3), (1,5,6), (7,10,2), (1,2,5))
    
    scala>   SetOfDigits.contains((1, 2, 5))
    res0: Boolean = true
    
    scala>   SetOfDigits.contains((1, 2, 4))
    res1: Boolean = false
    

    contains 在你的集合中找到一个元素,如果该元素不存在,它返回 false,在我看来看起来好多了。

    针对您的评论,我将第一个列表展平,然后使用forAllcontains

    scala> val setOfDigits1 = Set((0,2,3),(1,5,6),(7,10,2),(1,2,5)).flatMap { case(a,b,c) => Set(a,b,c)}
    setOfDigits1: scala.collection.immutable.Set[Int] = Set(0, 5, 10, 1, 6, 2, 7, 3)
    
    scala>   val setOfDigits2 =  Set(1,2,3,16,20,7)
    setOfDigits2: scala.collection.immutable.Set[Int] = Set(20, 1, 2, 7, 3, 16)
    
    scala>   val setOfDigits3 =  Set(1,2,3,10)
    setOfDigits3: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 10)
    
    scala>   setOfDigits2.forall(i => setOfDigits1.contains(i))
    res8: Boolean = false
    
    scala>   setOfDigits3.forall(i => setOfDigits1.contains(i))
    res9: Boolean = true
    

    请注意,我已将第一个列表从List[(Int, Int, Int)] 展平为List[Int],然后forAll 评估一个谓词,该谓词必须对所有元素都为真,而contains 完成其余部分。

    【讨论】:

    • 好吧,这对我来说已经解决了,但我还有另一个问题!假设我的列表 SetOfDigits 包含上面的元组,我想比较另一个包含: Set(1,2,3,16,20,7) ... 如果所有数字都是in SetOfDigits 在另一个 Set 中出现一次,所以只检查那些既包含又忽略其他的?
    • @Bajro 我已经进行了编辑,答案太长,无法发表评论。
    【解决方案2】:

    我同意 Ende Neu 的回答。

    在一般情况下,您可以引入一个布尔变量,您可以在 for-comprehension 中检查该变量以提前结束它。我更喜欢使用 return 关键字。

    def check(): Boolean = {
      var found = false
      for ((digit1,digit2,digit3) <- SetOfDigits if !found) {
        if ((1,2,5) == (digit1,digit2,digit3)) found = true
      }
      found
    }
    

    【讨论】:

    • 当您在找到所需值时应该停止时,遍历整个列表只是一种糟糕的编程。没错,return 不是惯用的 Scala,但也不是可变变量。
    【解决方案3】:

    如前所述,从if-else 产生结果,否则 for 理解返回Unit。与基于@EndeNeu API 的方法类似,也可以考虑

    xs.exists( _ == (1,2,5) )
    Boolean = true
    

    在找到第一个匹配项时停止对集合的迭代。

    还请注意,按照惯例,集合的标签以小写字母开头,即setOfDigits 而不是SetOfDigits,而类型和类则大写。

    【讨论】:

      【解决方案4】:

      您应该在 true 或 false 之前添加 return 语句以在第一次执行时停止。

      否则,您可以使用yield 收集每个子集的结果(您将获得布尔值列表)

      取决于您的期望。如果您想确保至少个子集满足结果,您的函数将如下所示:

      def check(): Boolean = {
          val s = for ((digit1,digit2,digit3) <- SetOfDigits) {
            if ((1,2,5) == (digit1,digit2,digit3))
              return true
          }
          false
        }
      

      【讨论】:

        猜你喜欢
        • 2014-12-19
        • 2021-05-04
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 2020-09-19
        • 1970-01-01
        相关资源
        最近更新 更多