问题描述
我需要创建一个函数,该函数需要一个double并根据第一个列表返回新列表,该列表包括第一个列表中属于范围的元素的绝对值。我需要使用过滤。我有个主意,但是没有用。对不起,也许我的问题很简单,但是我是一个初学者:)
var numbersReal = List(2.25,-1,-3,7.32,0.25,-6,2,1,2.99,3.02,0)
def magicFilter(list: List[Double]): List[Double] = {
var newList = List[Double]()
list.foreach {element => if (-5 <= element && element <= 12) newList += scala.math.abs(element) }
newList.toList
}
println(magicFilter(numbersReal))
解决方法
最佳实践解决方案
您可以结合使用
轻松完成此操作-
filter
:仅保留满足给定谓词/条件的元素。对我们来说,它将只保留[-5,12] 中的元素
-
map
:将函数应用于每个元素。对于我们来说,它将具有绝对价值。
numbersReal.filter(e => e >= -5 && e <= 12).map(math.abs)
“一次性”实现此目标的另一种方法是使用collect
,它结合了filter
和map
:
numbersReal.collect { case e if e >= 5 && e <= 12 => math.abs(e) }
我个人发现第一种解决方案在这种特殊情况下更具可读性,但这是一个见解。
通常,无需借助var
或任何可变集合即可解决这些问题。 Scala的集合是其最大的资产之一,因为它们包含了许多这些原始操作,并且可以通过组合使用它们来解决大多数问题。
关于您建议的解决方案的说明
您的解决方案本身并不是错误的,但是实现逻辑很容易出错,该逻辑已经是filter
,map
和collect
等收集方法的一部分。如果您想解决问题,只需将newList += ...
替换为newList :+= ...
。这是因为使用List
(或如果要添加list :+ element
,则将元素添加到不可变的element +: list
中)。 list :+= element
是list = list :+ element
的语法糖。再说一次,这些不是您经常会遇到的结构,因为这种样式通常会皱眉,除非您知道有充分的理由使用可变性。