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肯定是我还不太习惯使用的东西,但您向我展示了一个很棒的用例!