我是使用Scala的新手。
我有一个Scala Vector
包含Person
个对象,我需要在其上循环并将Vector的每个元素传递给方法personCollector
,其返回值也是Vector。从for
循环下面的Scala REPL输出中可以看出,它打印了由personCollector
返回的Vector三次,这是因为people
Vector包含三个条目。但是我想要打印personCollector
返回的向量只有一次,即for循环迭代结束后。
在Java中我可以按照以下方式执行:
var peopleWithFirstName = null;
for (Person p : people)
peopleWithFirstName = firstNameCollector(p);
System.out.println(peopleWithFirstName);
但是我无法想象在Scala中执行上述操作.Below是我的Scala代码。
Welcome to Scala version 2.10.4 (Java HotSpot(TM) Server VM, Java 1.7.0_04).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class Person(
| firstName: Option[String],
| middleName: Option[String],
| lastName: Option[String] )
defined class Person
scala> def isFirstNameValid(person: Person) = person.firstName.isDefined
isFirstNameValid: (person: Person)Boolean
scala> def personCollector(isValid: (Person) => Boolean) = {
| var validPeople = Vector[Person]()
| (person: Person) => {
| if(isValid(person)) validPeople = validPeople :+ person
| validPeople
| }
| }
personCollector: (isValid: Person => Boolean)Person => scala.collection.immutable.Vector[Person]
scala> val p1 = Person(Some("First Name"), Some("Middle Name"), Some("Last Name"))
p1: Person = Person(Some(First Name),Some(Middle Name),Some(Last Name))
scala> val p2 = Person(None, Some("Middle Name"), None)
p2: Person = Person(None,Some(Middle Name),None)
scala> val p3 = Person(Some("First Name"), None, None)
p3: Person = Person(Some(First Name),None,None)
scala> val people = Vector(p1, p2, p3)
people: scala.collection.immutable.Vector[Person] = Vector(Person(Some(First Name),Some(Middle Name),Some(Last Name)), Person(None,Some(Middle Name),None), Person(Some(First Name),None,None))
scala> val firstNameCollector = personCollector(isFirstNameValid)
firstNameCollector: Person => scala.collection.immutable.Vector[Person] = <function1>
scala> for (p <- people)
| println(firstNameCollector(p))
Vector(Person(Some(First Name),Some(Middle Name),Some(Last Name)))
Vector(Person(Some(First Name),Some(Middle Name),Some(Last Name)))
Vector(Person(Some(First Name),Some(Middle Name),Some(Last Name)), Person(Some(First Name),None,None))
感谢。
答案 0 :(得分:2)
我不完全确定你的实际目标是什么。我猜你想要实现的目标似乎可以通过filter
和map
更好地解决:
filter
充当验证者,即people.filter(isFirstNameValid)
。这将返回具有已定义名字的所有人的集合 - 这是您想要的吗?map
用作所需字段的提取器,在本例中为名字。总体而言people.filter(isFirstNameValid).map(_.firstName)
,以防您希望您的收藏品代表名字而不是完整的人。如果您还希望将Option
(名字)转换为具体值,则可能需要使用flatMap
(这也使得不需要显式验证)。如果您真的想要坚持基于修改外部状态的解决方案,您必须将可变变量放在外部范围中,例如......