【问题标题】:Check for the presence of a sub-list检查是否存在子列表
【发布时间】:2014-08-28 09:43:46
【问题描述】:

您能否提供一种执行(可能是惯用的)方法来检查列表 A 是否是给定列表 B 的子列表?

例如

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

【问题讨论】:

  • 不清楚您想要的是子集还是切片。例如,List(1,3)List(1,2,3) 的子列表(很明显,它应该是 List(1,3,5) 的子列表)?

标签: list scala scala-collections


【解决方案1】:

一种方法是使用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

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

【讨论】:

  • 在实践中,不应将List(1, 2, 3, 4) 之类的内容放在 lambda 中,因为它会一遍又一遍地创建列表。
  • 如果订单很重要:def isSubList[A] (short:Seq[A], long:Seq[A]): Boolean = long.containsSlice(short)。归功于下面的海报,如果这有帮助,请点赞他们的帖子!
【解决方案2】:

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

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

【讨论】:

  • 更具可读性:def isSubList[A] (short:Seq[A], long:Seq[A]): Boolean = long.containsSlice(short)
【解决方案3】:

另一种解决方案:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多