我想编写一个算法,该算法匹配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循环,但这不起作用。
所以我最终不知道如何解决这个问题。
任何人都可以帮助我吗?
答案 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)
,如果列表的头部在a
和b
范围内,则会检查列表的头部。如果是,则预先设置为结果列表。
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)
如果您将许多不同的标准链接在一起以得出最终结果,那么这个版本非常好。它将应用标准列表与其实现细节分开。