如何删除子列表

时间:2016-07-04 13:06:12

标签: list scala

如何从列表中删除所有出现的子列表,例如

List(1, 2, 3, 4, 5, 6, 7, 4, 8, 9, 10, 5).removeSubList(4, 5)

应删除所有出现的(4,5)(按此顺序!),因此返回

List(1, 2, 3, 6, 7, 4, 8, 9, 10, 5)

3 个答案:

答案 0 :(得分:5)

使用indexOfSlice的递归解决方案:

def removeSubList(l: List[Int], sublist: List[Int]): List[Int] = l.indexOfSlice(sublist) match {
  case -1 => l
  case index => removeSubList(l.patch(index, Nil, sublist.length), sublist)
}

// all of these print List(1 ,2 ,3):
println(removeSubList(List(1,2,3), List(4,5)))
println(removeSubList(List(1,2,3,4,5), List(4,5)))
println(removeSubList(List(4,5,1,2,3), List(4,5)))
println(removeSubList(List(4,5,1,2,4,5,3), List(4,5)))

<强> EDITED

  • (感谢@ corvus_192)恢复使用indexOfSlice版本而不是diff,忽略了子列表顺序。
  • (感谢@The Archetypal Paul)使用patch更清晰地删除子列表

答案 1 :(得分:1)

使用 Tzach Zohar 的想法与不同的实现:

def removeSubList[T](list: List[T], sublist: List[T]): List[T] =
    if (list.containsSlice(sublist)) 
        removeSubList(list.diff(sublist), sublist)
    else list

答案 2 :(得分:0)

Tzach Zohar 想法的变体,但假设OP想要的结果不包括给定的子列表。处理sublist为空时的案例

  /**
    * Return `s` with no occurrence of `target` present
    *
    * @param s
    * @param target
    * @return The sequence free of any occurrence of the target slice
    */
  def removeCompletely[E](s: Seq[E], target: Seq[E]): Seq[E] = {
    if (s.isEmpty || target.isEmpty)
      s
    else
      removeCompletely0(s, target)
  }

  private def removeCompletely0[E](s: Seq[E], target: Seq[E]): Seq[E] = {
    val sliceIdx = s.indexOfSlice(target)
    if (sliceIdx >= 0) {
      val patched = s.patch(sliceIdx, s take 0, target.size)
      removeCompletely0(patched, target)
    }
    else {
      s
    }
  }