将对象列表映射到具有特定字段的对象列表,基于给定的字段元素列表。

huangapple go评论55阅读模式
英文:

map list of objects to be with specific field based on given list of the field elements

问题

我有一个人员列表,其中包含id为4、5、6的人:

case class Person(id: Int)

val people = List(Person(4), Person(5), Person(6))

现在我有一个整数id列表,其中包含1、2、3:

val ids = List(1, 2, 3)

我想要将人员映射到这个列表中的ids,假设人员列表和ids列表的大小相同,你会如何做?

期望结果:

people = List(Person(1), Person(2), Person(3))
英文:

I have list of Person, with ids 4,5,6 :

case class Person(id: Int)

val people = List(Person(4),Person(5),Person(6))

now i have int list of ids 1,2,3 :

val ids = List(1,2,3)

and I want to map people to be with the ids in this list, given that list of people and list of ids are the same size, how would you do that?

expected result:

people = List(Person(1),Person(2),Person(3))

答案1

得分: 4

人们.zip(ids).map{ case (p, id) => p.copy(id = id) }

英文:
people.zip(ids).map{ case (p, id) => p.copy(id = id) }

答案2

得分: 2

case class通常是不可变的,这就是为什么你通常会采用以下方式的方法(你可以在Scastie上玩弄这段代码):

case class Person(id: Int)

val people = List(Person(4), Person(5), Person(6))

val ids = List(1, 2, 3)

val newPeople =
  people.zip(ids).map { case (person, id) => person.copy(id = id) }

assert(newPeople == List(Person(1), Person(2), Person(3)))

如果你想要就地修改某些内容,你需要将其声明为var(而case class属性默认是val):

class Person(var id: Int)

val people = List(Person(4), Person(5), Person(6))

val ids = List(1, 2, 3)

people.zip(ids).foreach { case (person, id) => person.id = id }

assert(people == List(Person(1), Person(2), Person(3)))

上面的代码也可以在Scastie上找到,供你进行实验。

原则上,你可以将case class的属性声明为var,但通常认为case class是不可变的,因此你可能需要根据你正在开发的项目决定是否使用case class还是简单的class

在Scala中,不可变性通常被视为首选,除非你有非常充分的理由不这样做。虽然它可能会对垃圾回收器造成更多的压力,但通常它更容易编写自包含的代码,如果必须在线程之间共享数据,那么这是一个很好的特性。

英文:

case classes are generally immutable, which is why you would normally have an approach like the following (you can play around with this code here on Scastie):

case class Person(id: Int)

val people = List(Person(4), Person(5), Person(6))

val ids = List(1, 2, 3)

val newPeople =
  people.zip(ids).map { case (person, id) => person.copy(id = id) }

assert(newPeople == List(Person(1), Person(2), Person(3)))

If you want to mutate something in place, you will need to qualify it as a var (whereas case class attributes are implicitly vals):

class Person(var id: Int)

val people = List(Person(4), Person(5), Person(6))

val ids = List(1, 2, 3)

people.zip(ids).foreach { case (person, id) => person.id = id }

assert(people == List(Person(1), Person(2), Person(3)))

The code above is also available here on Scastie for your to play around with.

In principle you can make a case class attribute a var, but case classes are generally assumed to be immutable, so you might want to decide whether you want a case class or a simple class based on the project you are working on.

In Scala, immutability is generally regarded as preferable unless you have a very good reason not to. While it might cause more pressure on the garbage collector, it generally makes it easier to write code that is self-contained and it's a nice property to have if you have to share your data across threads.

huangapple
  • 本文由 发表于 2023年5月17日 15:38:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76269598.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定