1

我是使用 Scala 的新手。

我有一个Vector包含Person对象的 Scala,我需要在这些对象上循环并将 Vector 的每个元素传递给personCollector返回值也是 Vector 的方法。for从循环下面的Scala REPL 输出中可以看出,它打印了personCollector三次返回的向量,这是因为people向量包含三个条目。但是我想只打印personCollector一次返回的向量,即在for 循环迭代结束之后。

在Java中,我可以按照以下方式进行:

var peopleWithFirstName = null;
for (Person p :  people)
  peopleWithFirstName = firstNameCollector(p);

System.out.println(peopleWithFirstName);

但是我无法在 Scala 中执行上述操作。下面是我的 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))

谢谢。

4

1 回答 1

2

我不完全确定你的实际目标是什么。我想你想要实现的目标似乎可以通过filterand更好地解决map

  • filter在这种情况下用作验证器,即people.filter(isFirstNameValid). 这将返回具有已定义名字的所有人的集合——这是您想要的吗?
  • map用作所需字段的提取器,在本例中为名字。所以总的来说 people.filter(isFirstNameValid).map(_.firstName),如果您希望您的收藏代表名字而不是完整的人。如果您还想从Option(名字的)转换为具体的值,您可能想要使用它flatMap(这也使得显式验证变得不必要)。

如果您真的要坚持基于修改外部状态的解决方案,您必须将可变变量放在外部范围中,例如......

于 2014-04-28T10:47:51.363 回答