Scala分区/收集用法 [英] Scala Partition/Collect Usage

查看:234
本文介绍了Scala分区/收集用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用一个呼叫collect来创建2个新列表?如果没有,该如何使用partition做到这一点?

Is it possible to use one call to collect to make 2 new lists? If not, how can I do this using partition?

推荐答案

collect(在

collect (defined on TraversableLike and available in all subclasses) works with a collection and a PartialFunction. It also just so happens that a bunch of case clauses defined inside braces are a partial function (See section 8.5 of the Scala Language Specification [warning - PDF])

与异常处理一样:

try {
  ... do something risky ...
} catch {
  //The contents of this catch block are a partial function
  case e: IOException => ...
  case e: OtherException => ...
}

这是一种定义仅接受某些给定类型值的函数的简便方法.

It's a handy way to define a function that will only accept some values of a given type.

考虑在混合值列表上使用它:

Consider using it on a list of mixed values:

val mixedList = List("a", 1, 2, "b", 19, 42.0) //this is a List[Any]
val results = mixedList collect {
  case s: String => "String:" + s
  case i: Int => "Int:" + i.toString
}

collect方法的参数是PartialFunction[Any,String]. PartialFunction因为未为Any类型(即List的类型)和String的所有可能输入定义它,因为这是所有子句返回的内容.

The argument to to collect method is a PartialFunction[Any,String]. PartialFunction because it's not defined for all possible inputs of type Any (that being the type of the List) and String because that's what all the clauses return.

如果尝试使用map而不是collect,则mixedList末尾的double值将导致MatchError.使用collect会丢弃该值以及未定义PartialFunction的任何其他值.

If you tried to use map instead of collect, the the double value at the end of mixedList would cause a MatchError. Using collect just discards this, as well as any other value for which the PartialFunction is not defined.

一种可能的用途是将不同的逻辑应用于列表的元素:

One possible use would be to apply different logic to elements of the list:

var strings = List.empty[String]
var ints = List.empty[Int]
mixedList collect {
  case s: String => strings :+= s
  case i: Int => ints :+= i
}

尽管这只是一个例子,但使用可变变量这样的变量被许多人视为战争罪-所以请不要这样做!

Although this is just an example, using mutable variables like this is considered by many to be a war crime - So please don't do it!

很多更好的解决方案是使用两次收集:

A much better solution is to use collect twice:

val strings = mixedList collect { case s: String => s }
val ints = mixedList collect { case i: Int => i }

或者,如果您确定该列表仅包含两种类型的值,则可以使用partition,它会根据集合是否与某些谓词匹配来将集合拆分为值:

Or if you know for certain that the list only contains two types of values, you can use partition, which splits a collections into values depending on whether or not they match some predicate:

//if the list only contains Strings and Ints:
val (strings, ints) = mixedList partition { case s: String => true; case _ => false }

这里的要点是stringsints都是List[Any]类型,尽管您可以轻松地将它们强制返回为更安全的类型(也许通过使用collect ...)

The catch here is that both strings and ints are of type List[Any], though you can easily coerce them back to something more typesafe (perhaps by using collect...)

如果您已经有一个类型安全的集合,并且想对元素的其他属性进行拆分,那么事情对您来说会容易一些:

If you already have a type-safe collection and want to split on some other property of the elements, then things are a bit easier for you:

val intList = List(2,7,9,1,6,5,8,2,4,6,2,9,8)
val (big,small) = intList partition (_ > 5)
//big and small are both now List[Int]s

希望总结一下这两种方法如何为您提供帮助!

Hope that sums up how the two methods can help you out here!

这篇关于Scala分区/收集用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆