Scala如何在Seq中追加或删除项目

时间:2015-02-20 10:23:35

标签: scala immutability case-class seq

我有以下课程

case class User(userId: Int, userName: String, email: String,   
password:     
String) {
def this() = this(0, "", "", "")
}

case class Team(teamId: Int, teamName: String, teamOwner: Int,   
teamMembers: Seq[User]) {
def this() = this(0, "", 0, Nil)
}

我想在teamMembers中添加或者用户:Seq [User]。我尝试了几种方式:

Team.teamMembers :+ member
Team.teamMembers +: member

什么都行不通:)。请求建议我如何在teamMembers中添加或删除项目:Seq [User]。

提前致谢!

4 个答案:

答案 0 :(得分:1)

创建一个操作,返回添加了成员​​的新Team,例如

我认为您的其他代码存在的问题是您正在尝试更改不可变变量。案例类团队中的teamMember字段是一个不可变的val,因此使用操作更改它不会更改其中包含的内容 - 它只会返回一个附加值的新序列,但不会影响案例中的值班组。

case class Team(teamId: Int, teamName: String, teamOwner: Int,   teamMembers: Seq[User]) {

    def this() = this(0, "", 0, Nil)

    // Operation returns a new Team object which has all elements of the previous team plus an additional member appended to the team members.
    def addMember(member: User) : Team = Team(teamId, teamName, teamOwner, teamMembers :+ member)

}

答案 1 :(得分:1)

你没有提到你使用哪种Seq。

如果是scala.collection.mutable.Seq,您可以添加到此序列。

但是,大多数更改都使用了immutable.Seq,这是Scala的默认设置。这意味着您无法添加它,但您可以创建一个包含所有项目+新项目的新项目。

scala开箱即用,你可以这样做 -

  val team =Team(0,"", 0, Seq[User]())
  val member = User(0, "","", "")

  val teamWithNewMemebr = team.copy(teamMembers = team.teamMembers :+ member)

但如果你有很多筑巢,或者你必须做很多事情,那就变得非常难看了。

要克服这种复杂的语法,您可以使用scalazmonocle等库,为您提供镜头

以下是如何使用镜头http://eed3si9n.com/learning-scalaz/Lens.html

的一个很好的示例

答案 2 :(得分:0)

来自the doc的加号(+)运算符:

  

[用例]带有前置元素的序列的副本

所以+会产生一个 new 集合,并附加您的附加元素。你在使用这个新系列。

答案 3 :(得分:0)

嗯......默认情况下,parameter attributes中的case classes immutable都是thread-safe

这样做是为了促进Separation of state and behaviour编程。此外,应该注意的一个主要问题是,这在某种程度上也促进了OOP的原始概念(类似于Smalltalk,在被Java OOP转换之前)。

嗯......分离国家和行为。所以...基本上是thread-safety遇到state的理想情况。

我个人喜欢这样做 - 在case classbehaviour,并将所有companion object移至case class User( userId: Int, userName: String, email: String, password: String ) object User { def apply(): User = User( 0, "", "", "" ) } case class Team( teamId: Int, teamName: String, teamOwner: Int, teamMembers: Seq[ User ] ) object Team { def apply(): Team = Team( 0, "", 0, Nil ) // since addMember is a behavior, it belongs here. // Also... since we are immutable... addMember name does not make much sense... // Let's call it withMember def withMember( team: Team, user: User ): Team = { team.copy( teamMembers = team.teamMembers :+ user ) } }

val user = User()

val team = Team()

val teamWithMember = Team.withMember( team, user )

现在,你必须像这样使用它,

   case class Team( teamId: Int, teamName: String, teamOwner: Int, var teamMembers: Seq[ User ] )

object Team {

    def apply(): Team = Team( 0, "", 0, Nil )

    // since addMember is a behavior, it belongs here.
    // Now we can keep name addMember
    def addMember( team: Team, user: User ): Unit = {
      team.teamMembers = team.teamMembers :+ user
    }

}

但是......如果......(就像在一个非常罕见的情况下),如果你真的"希望(控制你的欲望......控制)让它变得可变

val user = User()

val team = Team()

team.addMember( user )

并像这样使用它,

{{1}}