在Scala中匹配具有两个值的列表

时间:2016-06-07 02:23:22

标签: list scala functional-programming match

我想编写一个算法,该算法匹配Scala中带有两个值的列表。

例如,如果我有以下列表:

val list = List(1, 3, 6, 8, 9, 14, 18)

并且有两个值:

val a = 4

val b = 14

我想得到这个清单:

val result = List(6, 8, 9, 14)

如果考虑使用Scala的intersect方法,但只适用于两个列表。

我还考虑过使用for循环,但这不起作用。

所以我最终不知道如何解决这个问题。

任何人都可以帮助我吗?

5 个答案:

答案 0 :(得分:6)

哦,但你可以使用intersect,就像这样:

scala> List(1, 3, 6, 8, 9, 14, 18) intersect (4 to 14)
res1: List[Int] = List(6, 8, 9, 14)

您可以撤消订单,但结果集合类型不同。

scala> 4 to 14 intersect List(1, 3, 6, 8, 9, 14, 18)
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(6, 8, 9, 14)

外卖:Scala有很多不同的收藏类型,但其中很多都能很好地融合在一起。

答案 1 :(得分:1)

您可以使用以下语法指定列表:

val list = List(1, 3, 6, 8, 9, 14, 18)

它将为您创建scala.collection.immutable.List。如果我理解你的任务正确,这个oneliner可以解决你的问题:

list filter { element => a to b contains element }

所以如果a == 4,b == 14,你会得到:

res0: List[Int] = List(6, 8, 9, 14)

答案 2 :(得分:1)

使用递归,模式匹配和警卫。有趣的部分是警卫if(h >= a && h <= b),如果列表的头部在ab范围内,则会检查列表的头部。如果是,则预先设置为结果列表。

def slice(a: Int, b: Int, xs: List[Int]): List[Int] = xs match {
  case Nil                         => Nil
  case h::t if(h >= a && h <= b)   => h :: slice(a,b,t)
  case h::t                        => slice(a,b,t)
}

试验:

scala> slice(4,14, list)
res25: List[Int] = List(6, 8, 9, 14)

scala> slice(18,20, list)
res26: List[Int] = List(18)

scala> slice(1,3, list)
res27: List[Int] = List(1, 3)

scala> slice(-2,0, list)
res28: List[Int] = List()

...

尾部递归实现作为练习留下。 :)

答案 3 :(得分:1)

使用for comprehension,

for ( i <- xs if i >= 4 && i <= 14) yield i

为了便于使用,请考虑这个隐式类

implicit class OpsList(xs: List[Int]) {
  def segment(a: Int, b:Int) = for ( i <- xs if i >= a && i <= b) yield i 
}

等等

xs.segment(4,14)
List(6, 8, 9, 14)

答案 4 :(得分:0)

Knight71的评论是最简洁,最全面,最有效的答案,因为它不仅仅适用于Ints,并且不需要搜索每个元素的整个第二个列表第一个清单:

val result = list filter (x => x >= 4 && x <= 14)

您可能想要创建一个功能,使您的意图更加清晰:

def between(a: Int, b: Int)(x: Int): Boolean = x >= a && x <= b

val result = list filter between(4, 14)

如果您将许多不同的标准链接在一起以得出最终结果,那么这个版本非常好。它将应用标准列表与其实现细节分开。