【问题标题】:Why is my expression not being returned in Scala?为什么我的表达式没有在 Scala 中返回?
【发布时间】:2020-04-30 06:22:28
【问题描述】:

我有以下代码:

def foo(str: String, key: Char) : String = {

  breakable{
    for(it <- 0 until str.length){
      if(str.charAt(it) != key){
        str.slice(0, it) + str.slice(it+1, str.length)
        break
      }
    }
  }
  str
}

但是,str.slice(0, it) + str.slice(it+1, str.length) 永远不会返回,只有 str。

有谁知道我该如何解决这个问题?

【问题讨论】:

  • 在scala中如果没有return关键字,最后一句会被返回。由于最后一句是str,因此将返回此值。您不会在代码中以任何方式更改 str。
  • 似乎您试图找到一些非法符号并将其从字符串中首次出现,您可以通过 replaceFirst 方法简单地做到这一点:str.replaceFirst(key.toString, "")
  • 比这更复杂,我只是发布了问题的基本部分。由于抄袭的原因,我不能发布其余的内容。当 if 语句为真时,我只需要能够返回 str.slice(0, it) + str.slice(it+1, str.length)。
  • if(){v} 没有else 返回一个Unit,无论v 的类型是什么。这段代码有几种代码味道。
  • 既然你说这是一项任务,那么值得一提的是你是什么,不被允许做什么。

标签: string scala methods return substring


【解决方案1】:

str 是一个 val,它不会在您的操作中更新...您忽略了该字符串添加的结果

您的代码几乎与以下内容完全相同:

def foo(str: String, key: Char) : String = str

如果您想继续更新结果,请尝试使用 var,或者在字符串上使用其他方法在不使用 var 的情况下实现相同效果...使用 var 可能是这样的:

import util.control.Breaks._
def foo(str: String, key: Char) : String = {
  var bar = str
  breakable {
    for(it <- 0 until str.length){
      if(str.charAt(it) != key){
        bar = str.slice(0, it) + str.slice(it+1, str.length)
      break
     }
    }
  }
  bar 
}

编辑: 正如您所说,您不能在作业中使用 var,请考虑使用 foldLeft 来解决同样的问题:

def foo(str: String, key: Char): String = {
  string
    .foldLeft("") {
      case (acc, c) =>
        if(c == key) acc
        else acc + c
    }
}

【讨论】:

  • 我不允许使用 'var' 作为这项作业的规则
  • 好的,那是另一回事...我只是想解释一下您的方法出了什么问题...您可能想尝试使用递归方法来执行此操作,或者使用折叠但可破坏的方法会返回给您结果是一个单元,所以你需要修改一些东西
  • 当我看到这是一项任务时,我会说你看看 foldLeft 或 foldRight 应该没问题...我猜你从来没有被要求使用 breakable
  • 投反对票的人可以提供一些关于这个答案有什么问题的反馈吗?
  • @LuisMiguelMejíaSuárez 我的反对票是第二个,它是在评论之后添加的。我与神秘的所有者和第一次投票的神秘原因完全无关。
【解决方案2】:

必须分两部分完成。首先,您在字符串中找到此字符的索引(如果存在)。现在,如果找到索引,则返回切片字符串,否则返回原始字符串。

我假设您不能使用某些 String 方法直接执行此操作...

如果您使用的是 Scala 2.13

def foo(string: String, key: Char): String = {
  val indexOption =
    string
      .lazyZip(LazyList.from(0))
      .find({ case (c, i) => c == key })
      .map({ case (c, i) => i })

  indexOption
    .map(index => string.slice(0, index) + string.slice(index + 1, string.length))
    .getOrElse(string)
}

或者,如果您使用的是 Scala 2.12,

def foo(string: String, key: Char): String = {
  val indexOption =
    string
      .toStream
      .zipWithIndex
      .find({ case (c, i) => c == key })
      .map({ case (c, i) => i })

  indexOption
    .map(index => string.slice(0, index) + string.slice(index + 1, string.length))
    .getOrElse(string)
}

【讨论】:

  • find + map 基本上是collectFirst。另外,我想最好只使用iterator.zipWithIndex,它与两个版本的Scala (以及2.11)都兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 2018-07-01
  • 2013-07-28
  • 2017-11-27
  • 1970-01-01
相关资源
最近更新 更多