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

Scala how to append or remove item in 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)
}

我想在团队成员中添加或用户:Seq[用户]。我尝试了几种方法:

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

没有任何效果:)。请告诉我如何从 teamMembers 添加或删除项目:Seq[User].

提前致谢!

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

[use case] A copy of the sequence with an element prepended

so + 将生成一个 new 集合,并在前面加上您的附加元素。你在使用这个新系列吗?

创建一个 return 添加了成员​​的新团队的操作,例如

我认为您的其他代码存在问题,您正在尝试更改不可变变量。 case class team 中的 teamMember 字段是一个不可变的 val,因此通过操作更改它不会更改其中包含的内容 - 它只会 return 一个附加了值的新序列,但 won '影响到案例中的那个 class 团队。

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)

}

嗯... case classes中的所有parameter attributes默认都是immutable

这样做是为了促进 thread-safe 编程。另外,应该注意的一件大事是,这在某种程度上也促进了 OOP 的原始思想(类似于 Smalltalk,在被 Java OOP 改造之前)。

嗯...状态和行为的分离。所以...基本上是 Separation of state and behaviour 遇到 thread-safety.

的理想情况

我个人的口味是 - 在 case class 中加入 state,然后将所有 behaviour 移动到 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 )

但是...万一...(非常罕见的情况),如果您"really"想要(控制您的欲望,伙计...控制)让它可变,那么

   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 )

你没有提到你使用的是哪个Seq。

如果是 scala.collection.mutable.Seq 你可以添加到这个 Seq.

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

开箱即用的 Scala 你可以这样做 -

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

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

但是如果你有很多嵌套或者你必须做很多,这会变得很丑陋。

为了克服这种复杂的语法,您可以使用像 scalaz, monocle 这样的库,它为您提供 Lenses

这里有一个关于如何使用 Lenses 的很​​好的示例http://eed3si9n.com/learning-scalaz/Lens.html