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
我有关注 类
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