Bir nesne listesini alanının listelerine dönüştürme

0

Soru

Alan1, alan2 ve alan3 alanlarını içeren MyObject içeren bir Listem[MyObject] var.

Bunu yapmanın etkili bir yolunu arıyorum :

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

Java'da şöyle bir şey yapardım :

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'da olduğum için daha işlevsel bir şey istiyorum ama parmağımı üzerine koyamıyorum.

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

En iyi cevabı

3

2 \ 3 alt grup alın unzip\unzip3

Başlangıç noktasını varsayarsak:

val objects: Seq[MyObject] = ???

3 Alt grubun tümünü almak için fermuarı açabilirsiniz:

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

Ya 3'ten fazla ilgili alt grubum varsa ?

Gerçekten daha fazla alt gruba ihtiyacınız varsa, kendinizinkini uygulamanız gerekir unzipN ancak çalışmak yerine Tuple22 Şahsen bir adaptör kullanırdım:


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

Notlar:

  • Değişim MyObjectsProjection ihtiyacınıza göre.
  • Bu bir Scala 2.12\2.11 vanilya perspektifinden.
2021-11-23 13:57:53

Scala 3 kullanıcıları için: genel tuple'dan yararlanabilirsiniz: elements.map(Tuple.fromProductTyped(_)).unzip3
gianluca aguzzi

Ya daha sonra 3'ten fazla alanım varsa ?
Robert Reynolds

Bile olsa MyClass sadece 2\3 ilgili alanı seçebileceğiniz daha fazla alan var unzip\unzip3. Daha büyük tuples için kendi uygulamalarınızı eklemeniz veya algoritmanızı yeniden düşünmeniz gerekir. TBH ile çalışmak yerine Tuple20 case sınıfı bir adaptör yapardım.
gatear

Gönderiyi genel bir adaptörle de güncelledim
gatear
2

Aşağıdakiler nesnelerinizi üç listeye ayıracaktır:

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

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................