检查是否存在子列表

时间:2014-08-28 09:43:46

标签: list scala scala-collections

您能否为我提供一种表现(可能是惯用)方式来检查列表A是否是给定列表B的子列表?

E.g。

isSubList(List(1,2), List(1,2,3,4)) // => true
isSubList(List(1,2), List(5,6,7,8)) // => false 

3 个答案:

答案 0 :(得分:17)

如果订单很重要,您可以使用containsSlice,它检查集合是否包含给定序列作为切片

def isSubList[A](l1:List[A], l2:List[A]) = l2.containsSlice(l1)

答案 1 :(得分:13)

一种方法是使用forallcontains

scala>   List(1, 2).forall(List(1, 2, 3, 4).contains)
res3: Boolean = true

scala>   List(1, 2).forall(List(5, 6, 7, 8).contains)
res4: Boolean = false

scala>   List(1, 2).forall(List(5, 6, 2, 9).contains)
res5: Boolean = false

请注意,此方法不考虑订购:

scala>   List(1, 2).forall(List(2, 1).contains)
res6: Boolean = true

也许你也可以使用Setintersect,但我认为这种方式更可取。

答案 2 :(得分:2)

还有一个解决方案:

def isSubList[A](short: List[A], long: List[A]): Boolean =
    long.tails exists (_.startsWith(short))

但是,如果列表首先转换为流,效率会更高:

def isSubList[A](short: List[A], long: List[A]): Boolean = {
    val sLong = long.toStream
    val sShort = short.toStream
    sLong.tails exists (_.startsWith(sShort))
}

这样,不是所有的尾巴都必须生成。还以短路方式评估startsWith