def filter(data : List[Int]) : List[Int] = {
if(data.length == 0){
return data;
}else{
var list: List[Int] = List();
var index = 0;
for((value,index) <- data.zipWithIndex){
if(list(index) == list(index+1){
list = value :: list;
//println(list(index));
}
}
}
return list
}
}
我的功能有问题。 'data'是一个int数组,此函数需要过滤彼此相邻的所有重复项。例如{1,2,3,3,4,3,1}将过滤到{1,2,3,4,3,1}。此函数当前正在抛出数组超出范围的异常。我对scala的了解非常有限,所以由于缺乏知识,请保持所有答案简单。感谢您提供的所有帮助:D。
答案 0 :(得分:1)
通过索引访问列表并为结果创建另一个列表是一种代码味道。这是另一种递归和模式匹配的方法,它提供了一个相当简单的解决方案。
def filterNextTo(xs: List[Int]):List[Int] = xs match{
case h :: ht :: t => if(h == ht) filterNextTo(xs.tail) else h :: filterNextTo(xs.tail)
case h :: Nil => List(h)
case Nil => Nil
}
测试用例:
scala> xs
res7: List[Int] = List(1, 2, 3, 3, 4, 3, 1)
scala> filterNextTo(xs)
res8: List[Int] = List(1, 2, 3, 4, 3, 1)
这也可以通过zip
,filter
和map
来完成,但需要一些元组争论并处理一个我认为不太优雅的特殊情况。
更新为@ Paul的评论添加尾递归版本:
def filterNextTo(xs: List[Int]) = {
@tailrec
def filterNextToR(xs: List[Int], acc: List[Int]): List[Int] = xs match{
case h :: ht :: t if (h == ht) => filterNextToR(xs.tail, acc)
case h :: ht :: t if (h != ht) => filterNextToR(xs.tail, h :: acc)
case h :: t => (h :: acc).reverse
}
filterNextToR(xs, List[Int]())
}
答案 1 :(得分:1)
我认为折叠比显式递归更整洁,并且可以在长列表中使用:
ls match {
case Nil => Nil
case h :: t => t.foldLeft(List(h))
((a, b) => if (a.head == b) a
else b :: a)
.reverse
}
//> res0: List[Int] = List(1, 2, 3, 4, 3, 1)
答案 2 :(得分:0)
试试这个,
val list = List(1, 2, 3, 3, 4, 3, 1,1,5,5,6,6)
val y = list.sliding(2).toList
val x =y.filter(x=> (x.head != x.tail.head)).map(_.head) :+ (y.reverse.filter(x=> x.head !=x.tail.head)).head.tail.head