【问题标题】:Filter function in Scala not workingScala中的过滤器功能不起作用
【发布时间】:2015-03-12 19:43:57
【问题描述】:
   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' 是一个整数数组,此函数需要过滤所有相邻的重复项。例如 {1,2,3,3,4,3,1} 将是 {1,2,3,4,3,1} 的过滤器。此函数当前正在抛出数组越界异常。我在 scala 方面的知识非常有限,因此由于缺乏知识,请保持所有答案简单。感谢您提供的所有帮助:D。

【问题讨论】:

  • index+1 超出了最后一个列表元素的范围。此外,您正在以相反的顺序构建列表。您可能想要使用ListBuffer 或使用递归方法而不是使用for
  • 我的想法是使用 .reverse 将列表复制到另一个列表中

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


【解决方案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]())
}

【讨论】:

  • 你所做的是“头,尾”吗?我现在对这种语言很陌生
  • 是的。它正在分解列表以获取头部、尾部的头部和尾部。
  • 不是尾递归的,但长列表会堆栈溢出
  • 最后两个 case 语句可以替换为一个:case ys =&gt; ys 因为 filterNextTo 在这两种情况下都只返回其输入
【解决方案2】:

我认为折叠比显式递归更简洁,并且适用于长列表:

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)

【讨论】:

    【解决方案3】:

    试试这个,

      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
    

    【讨论】:

      猜你喜欢
      • 2020-11-24
      • 2020-01-04
      • 2021-05-05
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-16
      相关资源
      最近更新 更多