Scala中的过滤功能无法正常工作

时间:2015-03-11 17:12:02

标签: list scala if-statement for-loop filter

   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。

3 个答案:

答案 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)

这也可以通过zipfiltermap来完成,但需要一些元组争论并处理一个我认为不太优雅的特殊情况。

更新为@ 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