Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 无风险值或易碎品:如何;“中断”;在数组遍历中满足谓词时?_Arrays_Scala_Functional Programming_Scala Collections_Iterable - Fatal编程技术网

Arrays 无风险值或易碎品:如何;“中断”;在数组遍历中满足谓词时?

Arrays 无风险值或易碎品:如何;“中断”;在数组遍历中满足谓词时?,arrays,scala,functional-programming,scala-collections,iterable,Arrays,Scala,Functional Programming,Scala Collections,Iterable,如何将此编程逻辑写入函数方法签名?我试图循环/遍历一个数组,直到满足一个条件,然后在该条件下中断。我正在尽量避免scala.util.control.Breaks中的var和breakable。它利用闭包(在本例中为字典)检查是否满足条件/谓词。我的想法是在数组中循环,直到满足谓词。我还避免将数组转换为列表。使用数组是否不允许我拼接数组,例如,进行模式匹配 val dictionary = Array.fill(128)(false) def isUnique(array: Array[Cha

如何将此编程逻辑写入函数方法签名?我试图循环/遍历一个数组,直到满足一个条件,然后在该条件下中断。我正在尽量避免
scala.util.control.Breaks
中的
var
breakable
。它利用闭包(在本例中为
字典
)检查是否满足条件/谓词。我的想法是在数组中循环,直到满足谓词。我还避免将数组转换为列表。使用数组是否不允许我拼接数组,例如,进行模式匹配

val dictionary = Array.fill(128)(false)

def isUnique(array: Array[Char]): Option[Char] = {

  // traverse each element of the array {
  //     if a character.toInt is in the dictionary, insert into dictionary 
  //        exit loop, with the character which broke the loop
  //     else
  //        set dictionary(character.toInt) to true and continue looping
  // }
}
下面是一个示例用例:

val word = "abcdefggghijklmnopqrstuvqxyz".toArray
val charThatBrokeIt = isUnique(word)


编辑:也可以自由建议或建议其他返回类型,例如布尔、元组、Case类或任何其他返回类型<代码>选项[Char]对我来说可能不是一个好的结果值。例如我可能返回了
false
,以防环路过早中断(短路)或未中断。

早期中断总是提示递归

def isUnique(array: Array[Char]): Option[Char] = {
  def getDup(index: Int, acc: Set[Char]): Option[Char] =
    if (array.isDefinedAt(index))
      if (acc(array(index))) Some(array(index))
      else getDup(index+1, acc + array(index))
    else None
  getDup(0, Set.empty[Char])
}
用法:

val word = "abcdefggghijklmnopqrstuvqxyz".toArray
val charThatBrokeIt = isUnique(word)
//charThatBrokeIt: Option[Char] = Some(g)

首先,
String
已经起到了集合的作用,因此您应该只使用
String
而不是
Array[Char]
。其次,您可以利用惰性来允许短路,同时仍然使用
.view
将算法拆分为多个部分

def breaksUnique(字:字符串):选项[Char]={
val cumulativeSets=word.view.scanLeft(Set.empty[Char]){
val zipped=累积设置压缩字
val nondupsdrop=zipped dropWhile{case(set,char)=>!(set包含char)}
Nondupsdroped.map{{uu.\u 2}.headOption
}
前两行的编写方式就像它们处理整个单词一样,但由于它们在视图上操作,因此只能根据需要进行计算


cumulativeSets
是一组到目前为止已看到的每个字符的序列。如果您在“abb”上运行它,您将得到
Set(),Set(a),Set(a,b),Set(a,b)
。与原始单词结合使用
zip
,给出
(Set(),a),(Set(a),b),(Set(a,b),b)
。然后,我们只需删除集合中未出现字符的所有对,然后返回未删除的第一个元素。

那里的答案使用
var
。我正在尽力避免
var
。这个链接中唯一不使用var的答案来自fresskoma,它使用长尾递归模式匹配。如果你有更好的问题标题的建议,请告诉我。它们不是重复的。返回类型
选项[Char]
可能不是最佳类型,因此也可以随意编辑该类型。我知道其他解决方案可能有一些优点/缺点,例如将返回的值包装到可能在模式匹配中应用或不应用的case类中。
Try
在这里似乎有些过分,因为您知道
getDup
将始终返回-1或有效索引。@JoePallas;这只是一种简洁的方法,可以将结果包装成一个
选项
,但是,是的,有一种更好的方法可以达到目的。@jwvh谢谢。我真的希望Option[Char]类型不会限制您的解决方案。是否有更好的结论?我想返回一个布尔值,但我不确定这是否会增加或减少更多的值。因为如果没有重复的字母,我可以不检查任何字母。
选项[Char]
对我来说似乎有意义,但是,理想情况下,方法的配置文件应该由对调用方/客户端最有用/最有意义的内容来确定。实现问题应该是次要问题。返回类型可以,但方法命名有问题,一个名为
isUnique
的方法在逻辑上应该返回
Boolean
。哇。这是一个非常简洁、令人惊叹的解决方案。我仍在分解大部分内容,但这是我一直在寻找的东西!我正在寻找一个利用短路评估、不变性的解决方案,以及一个通过使用
视图
来关心运行时间的解决方案。关于这个解决方案,我最喜欢的是使用集合,它可以更清楚地描述预期的函数行为
dropWhile
scanLeft
,和Set肯定是我还不太习惯使用的东西,但您向我展示了一个很棒的用例!