【发布时间】:2018-05-14 07:46:40
【问题描述】:
我有几种方法可以伪造一个单词,我需要随机调用它们,直到实现创建“人为错误”。
我想调用一个随机方法,然后再调用另一个,直到没问题,但绝不会重复两次。
将它们放在一个数组(或列表)中意味着我每次尝试一个方法时都会重写一个数组,这是一个丑陋的计算复杂性,我想编写“Scala 风格”的代码,尽量减少 var 和可变性。
编辑:
Oleg Pyzhcov solution 运行良好,但现在我有一些带有字符串参数的函数,而其他没有。 如何将函数及其调用参数存储在集合中?
val rand: Random = new Random()
def m1(a: String): Boolean = rand.nextBoolean()
def m2(): Boolean = rand.nextBoolean()
def m3(a: String, b: String): Boolean = rand.nextBoolean()
def m4(): Boolean = rand.nextBoolean()
def tryUntilOk(): Unit = {
def out = rand.shuffle(Stream(m1 _, m2 _, m3 _, m4 _))
.map(method => method()) // calling without params so error
.find(result => result) // stop when a method return true
}
编辑 2:
详情
我有几种方法试图伪造一个词,但不能保证他们能做到。有的方法取动词的语气和时态,改变时态或语气,有的只取单词正确的写法去掉一些字母,还有的取名词的性和数来改变它的性。
我想在所有可能的方法中调用一个随机方法,如果它不能伪造单词(例如给定的名词仅以女性形式存在)然后随机调用另一个。重复这个操作,直到没有更多的方法可用,所以我们放弃了。 Oleg的解决方案对于随机部分很好,但是我找不到如何给方法调用参数。
具体例子:
package Counterfeiters
import Words.Noun
object Noun extends Counterfeiter[Noun] {
override def counterfeit(word: Noun): Unit = {
// For now I call methods without random order
// This one take only one String param
// And split letters that are duplicated like boot -> bot
word.currentWriting = splitDoubleLetters(word.correctWriting)
// Then we compare word.currentWriting and word.correctWriting
// If the word wasn't containing double letters, it isn't counterfeited
if (!word.isCounterfeited)
// This one take 5 String params
// And counterfeit the gender or the number of the word, randomly
word.currentWriting = counterfeitGenderNumberWord("N", word.correctWriting, word.lemma, word.gender, word.number)
}
}
要应用 Oleg 的解决方案,我只需要找到如何将方法存储在集合中,并带有相应的参数。在这种情况下(splitDoubleLetters, (word.correctWriting)) 和(counterfeitGenderNumberWord, ("N", word.correctWriting, word.lemma, word.gender, word.number))。
解决方案
我按照 Oleg 在评论中的建议做了:
object Noun extends Counterfeiter[Words.Noun] {
override def counterfeit(word: Words.Noun): Unit = {
if (word.isCounterfeited) return
def split: () => String = () => splitDoubleLetter(word.correctWriting)
def ctftGenderNumber: () => String = () => counterfeitGenderNumberWord("N", word.correctWriting, word.lemma, word.gender, word.number)
val methods: immutable.Seq[() => String] = Stream(split, ctftGenderNumber)
val res: Option[String] = randomizer.shuffle(methods) // Shuffle methods
.map(method => method()) // Call them one by one
.find(result => result != word.correctWriting) // Until one counterfeit the word
word.currentWriting = res match {
case None => word.correctWriting // If every methods failed
case _ => res.get
}
}
}
SergGr explained 一个可能的架构,我会很清楚地适应这个。
如果您想更好地了解我的工作,可以在 GitHub 上找到我的完整项目代码。
【问题讨论】:
-
VNourdin,不清楚你想要实现什么。您可能应该与我们分享您的“丑陋”代码,以便我们可以改进它以保留逻辑。特别是,该代码中的函数调用参数来自哪里?您只需要将您的方法转换为部分应用的函数吗?是别的吗?
-
好的,我试着澄清一下并举个具体的例子。
标签: scala function random methods