我有以下程序,其中包含带模式匹配的递归函数。 此代码有效
def randomSelect(num:Int, lst:List[Symbol]):List[Symbol] = (num, lst) match{
/** traveerse list recursively extracting randomelemnents
*
*/
case (n, l) => {
if (n>0) {
println("At " + n + " we got:" + l)
val rnd = getRandom(l.length)
val item = l(rnd)
lst(rnd) :: randomSelect(n - 1, l.filter(it => it != item))
} else List[Symbol]()
}
}
而以下情况并非如此。我无法理解为什么
def randomSelect(num:Int, lst:List[Symbol]):List[Symbol] = (num, lst) match{
/** traveerse list recursively extracting randomelements
*
*/
case (n, mylist) => {
val rnd = getRandom(mylist.length)
val item = mylist(rnd)
lst(rnd) :: randomSelect(n - 1, mylist.filter(it => it != item))
}
case (0, mylist) => List[Symbol]()
}
在第二个conde片段中,永远不会调用case(0,mylist)。
我错过了什么?
亲切的问候 马可答案 0 :(得分:1)
现在你有类似的东西:
if (the input is a Tuple2) {
do something
} else if (the input is a Tuple2 with a 0 as the first item) {
do other thing
}
case (n, mylist) =>
匹配(0, List(...))
您需要为第一个表达式添加一个保护或重新排序您的案例,以便首先达到0个案例。
所以:
case (0, mylist) => List[Symbol]()
case (n, mylist) => {
val rnd = getRandom(mylist.length)
val item = mylist(rnd)
lst(rnd) :: randomSelect(n - 1, mylist.filter(it => it != item))
}
或
case (n, mylist) if n > 0 => {
val rnd = getRandom(mylist.length)
val item = mylist(rnd)
lst(rnd) :: randomSelect(n - 1, mylist.filter(it => it != item))
}
case (0, mylist) => List[Symbol]()
答案 1 :(得分:0)
在以下语句中:case (n, mylist)
,n
是一个绑定到该位置中任何值的变量,在您的情况下为num: Int
。所以n
绑定到所有整数值。当它恰好为0时,你的第一个案例就匹配它,因此永远不会达到第二个案例陈述。
有两种方法可以解决这个问题。第一:
case (n, mylist) if n > 0 => {
val rnd = getRandom(mylist.length)
val item = mylist(rnd)
lst(rnd) :: randomSelect(n - 1, mylist.filter(it => it != item))
}
case _ => List.empty[Symbol]
我使用了通配符,因为您没有使用列表或n
。
第二种方式:
case (0, _) => List.empty[Symbol]
case (n, mylist) => {
val rnd = getRandom(mylist.length)
val item = mylist(rnd)
lst(rnd) :: randomSelect(n - 1, mylist.filter(it => it != item))
}
答案 2 :(得分:0)
如前所述,对案例进行重新排序,以便首先评估最具体的案例。
然而,两种情况的模式匹配可以简化为if-else
表达式(不必通过警卫复制if-else
),注意在这种递归方法中,基本(平凡)情况可能是首先宣布,主要是为了提高可读性,
def randomSelect(n:Int, l:List[Symbol]):List[Symbol] = {
if (n <= 0) List[Symbol]()
else {
println("At " + n + " we got:" + l)
val rnd = getRandom(l.length)
val item = l(rnd)
lst(rnd) :: randomSelect(n - 1, l.filter(it => it != item))
}
}