在 Scala 中查找与谓词匹配的项目
Posted
技术标签:
【中文标题】在 Scala 中查找与谓词匹配的项目【英文标题】:Finding an item that matches predicate in Scala 【发布时间】:2012-03-22 07:56:01 【问题描述】:我正在尝试在 scala 集合中搜索列表中与某个谓词匹配的项目。我不一定需要返回值,只是测试列表是否包含它。
在 Java 中,我可能会这样做:
for ( Object item : collection )
if ( condition1(item) && condition2(item) )
return true;
return false;
在 Groovy 中,我可以执行以下操作:
return collection.find condition1(it) && condition2(it) != null
在 Scala 中执行此操作的惯用方式是什么?我当然可以将 Java 循环样式转换为 Scala,但我觉得有一种更实用的方法可以做到这一点。
【问题讨论】:
我不会太担心惯用性或功能性:Scala 库中的集合具有exists
和 find
方法(区别在于 find
返回元素)返回为一旦找到元素。两者都是用var
和while
循环实现的,看起来与你的java 实现非常相似(除了将谓词作为参数)。
【参考方案1】:
过滤并存在关键字以从列表中获取匹配值
val values = List(1,2,3,4,5,6,7,8,9,10,....,1000) //List -1
val factors= List(5,7) // List -2
//To get the factors of List-2 from List-1
values .filter(a => factors.exists(b => a%b == 0)) //Apply different logic for our convenience
给定的代码有助于从 2 个不同的列表中获取匹配值
【讨论】:
【参考方案2】:scala 的方式是使用exists
:
collection.exists(item => condition1(item) && condition2(item))
从 java 8 开始你可以使用anyMatch
:
collection.stream().anyMatch(item -> condition1(item) && condition2(item));
这比普通的 for 或 foreach 要好得多。
【讨论】:
【参考方案3】:测试值匹配谓词是否存在
如果您只是对测试某个值是否存在感兴趣,您可以使用....exists
scala> val l=(1 to 4) toList
l: List[Int] = List(1, 2, 3, 4)
scala> l exists (_>5)
res1: Boolean = false
scala> l exists (_<2)
res2: Boolean = true
scala> l exists (a => a<2 || a>5)
res3: Boolean = true
其他方法(一些基于cmets):
计算匹配元素
计算满足谓词的元素(并检查 count 是否 > 0)
scala> (l count (_ < 3)) > 0
res4: Boolean = true
返回第一个匹配元素
找到满足谓词的第一个元素(根据 Tomer Gabel 和 Luigi Plinge 的建议,这应该更有效,因为它会在找到一个满足谓词的元素时立即返回,而不是遍历整个 List)
scala> l find (_ < 3)
res5: Option[Int] = Some(1)
// also see if we found some element by
// checking if the returned Option has a value in it
scala> l.find(_ < 3) isDefined
res6: Boolean = true
测试是否存在精确值
对于我们实际上只检查一个特定元素是否在列表中的简单情况
scala> l contains 2
res7: Boolean = true
【讨论】:
如果您对对返回值感兴趣,请使用 findFirst。您还可以使用自命名函数获取计数。都采用相同的谓词。 是find
,不是findFirst
,但是是的,这比过滤整个列表更有效
@LuigiPlinge 我在您的更正中添加了 Tomer 的建议。谢谢!【参考方案4】:
使用过滤器:
scala> val collection = List(1,2,3,4,5)
collection: List[Int] = List(1, 2, 3, 4, 5)
// take only that values that both are even and greater than 3
scala> collection.filter(x => (x % 2 == 0) && (x > 3))
res1: List[Int] = List(4)
// you can return this in order to check that there such values
scala> res1.isEmpty
res2: Boolean = false
// now query for elements that definitely not in collection
scala> collection.filter(x => (x % 2 == 0) && (x > 5))
res3: List[Int] = List()
scala> res3.isEmpty
res4: Boolean = true
但如果你只需要检查使用exists
:
scala> collection.exists( x => x % 2 == 0 )
res6: Boolean = true
【讨论】:
是的,这看起来就像我正在寻找的方法。还在学习 Scala...谢谢。 简单一点collection exists x => condition1(x) && condition2(x)
@是的,我也加了这个
@om-nom-nom,是的,非常同步:)
@Stas 是的,它 exist
在第一次出现 true
时退出(双关语)以上是关于在 Scala 中查找与谓词匹配的项目的主要内容,如果未能解决你的问题,请参考以下文章