Преобразуйте список объектов в списки их полей

0

Вопрос

У меня есть список[MyObject], в котором MyObject содержит поля field1, field2 и field3.

Я ищу эффективный способ сделать :

Tuple3(_.map(_.field1), _.map(_.field2), _.map(_.field3))

На java я бы сделал что-то вроде :

Field1Type f1 = new ArrayList<Field1Type>();
Field2Type f2 = new ArrayList<Field2Type>();
Field3Type f3 = new ArrayList<Field3Type>();


for(MyObject mo : myObjects) {
    f1.add(mo.getField1());
    f2.add(mo.getField2());
    f3.add(mo.getField3());
}

Я хотел бы что-то более функциональное, так как я нахожусь в scala, но я не могу понять, в чем дело.

scala
2021-11-23 10:53:16
2

Лучший ответ

3

Получите 2\3 подгруппы с unzip\unzip3

Предполагая отправную точку:

val objects: Seq[MyObject] = ???

Вы можете распаковать архив, чтобы получить все 3 подгруппы:

val (firsts, seconds, thirds) =  
  objects
    .unzip3((o: MyObject) => (o.f1, o.f2, o.f3))

Что делать, если у меня более 3 соответствующих подгрупп ?

Если вам действительно нужно больше подгрупп, вам нужно реализовать свои собственные unzipN однако вместо того, чтобы работать с Tuple22 Я бы лично использовал адаптер:


case class MyObjectsProjection(private val objs: Seq[MyObject]) {
  
  lazy val f1s: Seq[String] =
    objs.map(_.f1)

  lazy val f2s: Seq[String] =
    objs.map(_.f2)

    ... 
  
  lazy val f22s: Seq[String] =
    objs.map(_.f3)
}

val objects: Seq[MyClass] = ???
val objsProjection = MyObjectsProjection(objects)

objs.f1s
objs.f2s
...
objs.f22s

Примечания:

  • Изменить MyObjectsProjection в соответствии с вашими потребностями.
  • Это с точки зрения Scala 2.12\2.11 ванили.
2021-11-23 13:57:53

Для пользователей scala 3: вы можете использовать универсальный кортеж: elements.map(Tuple.fromProductTyped(_)).unzip3
gianluca aguzzi

Что делать, если у меня будет более 3 полей позже ?
Robert Reynolds

Даже если MyClass имеет больше полей, вы можете выбрать всего 2\3 соответствующих поля с unzip\unzip3. Вам нужно добавить свои собственные реализации для больших кортежей или просто переосмыслить свой алгоритм. TBH вместо работы с Tuple20 я бы сделал адаптер класса case.
gatear

Я также обновил сообщение с помощью универсального адаптера
gatear
2

Далее ваши объекты будут разложены на три списка:

case class MyObject[T,S,R](f1: T, f2: S, f3: R)

val myObjects: Seq[MyObject[Int, Double, String]] = ???

val (l1, l2, l3) = myObjects.foldLeft((List.empty[Int], List.empty[Double], List.empty[String]))((acc, nxt) => {
  (nxt.f1 :: acc._1, nxt.f2 :: acc._2, nxt.f3 :: acc._3)
})
2021-11-23 11:17:18

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................