我现在正在学习Scala,我有一个场景,我必须将一个元素(比如num
)与列表中的所有元素进行比较。
假设,
val MyList = List(1, 2, 3, 4)
如果num
等于列表中元素的任何人,我需要返回true
。我知道使用head
和tail
函数以递归方式执行此操作,但有一种更简单的方法(我认为我能够使用foreach
来执行此操作,但是我不确定如何完全实现它?
答案 0 :(得分:10)
有很多可能性:
val x = 3
MyList.contains(x)
!MyList.forall(y => y != x) // early exit, basically the same as .contains
如果您打算经常这样做,您可以考虑将列表转换为Set,因为在最坏的情况下列表上的每个.contains
查找都与元素的数量成比例,而在Set上它是{{3} }
val mySet = MyList.toSet
mySet.contains(x)
或简单地说:
mySet(x)
答案 1 :(得分:3)
contains
方法非常适用于任何语言的列表。 Scala的List
也有它:
http://www.scala-lang.org/api/current/scala/collection/immutable/List.html
答案 2 :(得分:3)
正如其他人已经回答的那样,列表中的contains
方法就是这样做的,而且这是最容易理解/最有效的方法。
看看你的结束评论,你不能能够(以优雅的方式)与foreach
一起做,因为它返回Unit
。 Foreach为每个元素“做”了一些事情,但是你没有得到任何结果。它对于logging / println语句很有用,但它不能作为转换。
如果要单独对每个元素运行函数,可以使用map
,它返回应用函数结果的List。因此,假设num = 3,则MyList.map(_ == num)
将返回List(false, false, true, false)
。由于您正在寻找单个结果,而不是结果列表,因此这不是您所追求的。
为了将一系列事物折叠成单个结果,您将对数据使用 fold 。折叠涉及一个带有两个参数的函数(到目前为止的结果,以及列表中的当前事物)并返回新的运行结果。因此,这可以在第一个元素上工作,您还需要提供用于正在进行的结果的初始值(通常是某种零)。
在您的特定情况下,您最后需要Boolean
答案 - “找到的元素等于num
”。因此,运行结果将是“我到目前为止看到的元素等于num
”。这意味着初始值为false
。如果已经看到一个元素,或者当前元素等于true
,函数本身应返回num
。
将它们放在一起,它看起来像这样:
MyList.foldLeft(false) { case (runningResult, listElem) =>
// return true if runningResult is true, or if listElem is the target number
runningResult || listElem == num
}
一旦找到目标值,这就不具备停止的好处 - 并且它远不如调用MyList.contains
那么简洁。但作为一个教学示例,您可以从列表中的原始函数操作中自行实现。
答案 3 :(得分:2)
List
有一个方法:
val found = MyList.contains(num)