如何解决如何在Scala中某个元素之前删除重复的整数
我有一个列表,该列表可以在不需要的索引之前包含某些数字。例如:
val tempList: List[Any] = List(0,3,.,5,2,5)
我如何能够删除3之前的所有0,而又不滤除3之后的0?
解决方法
您可以使用dropWhile
。假设您要删除1之前的所有内容,
scala> val l = List(0,1,2,0)
l: List[Int] = List(0,0)
scala> l.dropWhile(_ == 0)
res1: List[Int] = List(1,0)
,
您需要做的是对dropWhile
的修改,我称之为filterWhile
。
一种利用Collection API的简单解决方案如下:
def filterWhile[A](
list: List[A]
)(filterP: A => Boolean,whileP: A => Boolean): List[A] = {
val (toFilter,unfiltered) = list.span(whileP)
toFilter.filter(filterP) ++ unfiltered
}
您可以使用此代码here on Scastie以及一些测试来验证它是否可以正常工作,如下:
def test[A](
input: List[A],expected: List[A]
)(filterP: A => Boolean,whileP: A => Boolean): Unit =
assert(
filterWhile(input)(filterP,whileP) == expected,s"input: $input,expected: $expected,got: ${filterWhile(input)(filterP,whileP)}"
)
test(
input = List(0,3,'.',5,5),expected = List(3,5)
)(filterP = _ != 0,whileP = _ != 3)
test(
input = List(0,expected = List(1,whileP = _ != 3)
test(
input = List(1,4),4)
)(filterP = _ < 5,whileP = _ < 5)
在您的情况下,特别需要做的就是按如下方式调用该函数:
filterWhile(tempList)(_ != 0,_ != 3)
第一个谓词说明如何过滤,第二个定义“ while”子句。我选择将谓词顺序与函数的名称对齐(它先说“过滤器”,然后是“ while”),但可以根据自己的喜好随意调整。无论如何,在这里使用命名参数可能是一件好事。
,结合列表中的现有功能,我想到了:
def filterUntil[A](list: List[A],filter: A => Boolean,cond: A => Boolean): List[A] = {
list.takeWhile(cond).filter(filter) ++ list.dropWhile(cond)
}
与@stefanobaghino的答案产生的结果几乎相同。
,这可以用foldLeft
完成,但是在这种情况下,我需要递归例程:
def remove(list: List[Any]): List[Any] = {
def loop(rem: List[Any],res: List[Any]): List[Any] =
rem match {
case Nil =>
res
case 0 :: tail =>
loop(tail,res)
case 3 :: _ =>
res ++ rem
case x :: tail =>
loop(tail,res :+ x)
}
loop(list,Nil)
}
remove(List(0,".",5))
// List(3,.,5)
请注意,这对于长列表来说并不是有效的,因为在长列表中添加到List
的尾部会非常慢。
此外,如注释中所述,您应尽可能避免使用Any
并使用更具体的类型。
[感谢@MikhailIonkin的简化]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。