2016-01-20 12 views
9

Say örneğin, benBir rdd'ye bir vaka sınıfını nasıl yerleştiririm ve bir tuple (çift) gibi davranabilirim?

case class Foo(k:String, v1:String, v2:String) 

Ben kıvılcım bir tuplea dönüştürmeden, böyle bir şey amaçları için bir başlığın olarak bu tanımasını alabilir miyim basit bir olay sınıf var, demek bir harita veya keyBy adım .

val rdd = sc.parallelize(List(Foo("k", "v1", "v2"))) 
// Swap values 
rdd.mapValues(v => (v._2, v._1)) 

Böyle bir işlemden sonra orijinal vaka sınıfını kaybederse bile umrumda değil. Şanssız bir şekilde denedim. Scala’ya oldukça yeni oldum, bir şey mi özledim?

case class Foo(k:String, v1:String, v2:String) 
    extends Tuple2[String, (String, String)](k, (v1, v2)) 

düzenleme: vaka sınıfı Tuple2 uzanır Yukarıdaki pasajı, bu RDD sınıf ve işlevleri, mapValues, değerler, reduceByKey olarak PairRDDFunctions, bir demet gibi davranın ve izin vermez istenen etkiyi üretmez

+2

Olası kopyası [In Scala, bir vaka sınıfını bir tuple dönüştürmenin kolay bir yolu var mı?] (Http://stackoverflow.com/questions/8087958/in-scala-is-there-an-easy- yolu-dönüştürmek-bir-durumda-sınıf-içine-bir-tuple) – Haspemulator

+0

Hayır, bunun farkındayım. Bir tuple kıvılcımı verildiğinde normalde mapValues ​​gibi ekstra işlemlere izin verir, ancak bu uzatma teçhizatı bu –

+0

'u almaz. Bu yüzden burada ne yapmak istediğinizi anlamaya çalışıyorum. Bir vaka sınıfınız olduğunu ve bu vaka sınıfında tuple benzeri işlevleri gerçekten bir tuple çevirmeden gerçekleştirmek istediğinizi mi söylüyorsunuz? –

cevap

8

TupleN'u genişletmek, birkaç nedenden ötürü iyi bir fikir değildir, bunun en iyisi, kullanımdan kaldırılmış olması ve 2.11'in TupleN'u bir vaka sınıfı ile genişletmek bile mümkün değildir. Foo'u kasa dışı bir sınıf haline getirmiş olsanız bile, -deprecation ile 2.11 olarak tanımlamanız size şunu gösterecektir: "uyarı: paket scala'daki Tuple2 sınıfından devralma onaylanmaz: Tupller gelecek sürümde son haline getirilir." Ne önemsediğiniz kullanım kolaylığı ve bir tuplea dönüşüm (neredeyse kesinlikle ihmal edilebilir) yükü sakıncası yoksa

, böyle bir dönüşüm ile PairRDDFunctions tarafından sağlanan sözdizimi ile RDD[Foo] zenginleştirebilirsiniz:

import org.apache.spark.rdd.{ PairRDDFunctions, RDD } 

case class Foo(k: String, v1: String, v2: String) 

implicit def fooToPairRDDFunctions[K, V] 
    (rdd: RDD[Foo]): PairRDDFunctions[String, (String, String)] = 
    new PairRDDFunctions(
     rdd.map { 
     case Foo(k, v1, v2) => k -> (v1, v2) 
     } 
    ) 

Ve sonra:

scala> val rdd = sc.parallelize(List(Foo("a", "b", "c"), Foo("d", "e", "f"))) 
rdd: org.apache.spark.rdd.RDD[Foo] = ParallelCollectionRDD[6] at parallelize at <console>:34 

scala> rdd.mapValues(_._1).first 
res0: (String, String) = (a,b) 

Foo çalışmıyor Tuple2[String, (String, String)] uzanan ile versiyon olmasıdır nedeni RDD.rddToPairRDDFunctions targe t RDD[Tuple2[K, V]] ve RDD, tür parametresinde eşdeğer değildir, bu nedenle RDD[Foo], RDD[Tuple2[K, V]] değildir. Daha basit bir örnek hale getirebileceğini bu net: o

case class Box[A](a: A) 

class Foo(k: String, v: String) extends Tuple2[String, String](k, v) 

class PairBoxFunctions(box: Box[(String, String)]) { 
    def pairValue: String = box.a._2 
} 

implicit def toPairBoxFunctions(box: Box[(String, String)]): PairBoxFunctions = 
    new PairBoxFunctions(box) 

Ve:

scala> Box(("a", "b")).pairValue 
res0: String = b 

scala> Box(new Foo("a", "b")).pairValue 
<console>:16: error: value pairValue is not a member of Box[Foo] 
     Box(new Foo("a", "b")).pairValue 
          ^

Ama Box covariant ...

case class Box[+A](a: A) 

class Foo(k: String, v: String) extends Tuple2[String, String](k, v) 

class PairBoxFunctions(box: Box[(String, String)]) { 
    def pairValue: String = box.a._2 
} 

implicit def toPairBoxFunctions(box: Box[(String, String)]): PairBoxFunctions = 
    new PairBoxFunctions(box) 

... herşey yolunda yaparsanız:

scala> Box(("a", "b")).pairValue 
res0: String = b 

scala> Box(new Foo("a", "b")).pairValue 
res1: String = b 

Yapamazsın Bununla birlikte, RDD kovaryantı olun, bu nedenle sözdizimini eklemek için kendi örtük dönüşümünüzü tanımlamak en iyi seçimdir. Şahsen büyük olasılıkla dönüşümü açıkça yapmayı tercih ederim, ancak bu, örtük dönüşümlerin nispeten dehşet verici bir kullanımıdır.

İlgili konular