2016-12-12 4 views
4

私はファイルを読みたい場合は、マイファイル形式は次のとおりです。 12334本:23、単語:21、教師:23scala.MatchError:[Ljava.lang.String; (Ljava.lang.String [クラスの;)

val fp = "/user/user_id.txt" 
    sc.textFile(fp).map { s => 
    val Array(did, info_s) = s.split("\t") 
    val info = info_s.split(",").map { kv => 
     val Array(k, v) = kv.split(":") 
     (k, v.toDouble) 
    }.toSeq 
    (did, info) 
    } 

このスカラエラーが発生しました。

scala.MatchError: [Ljava.lang.String;@51443799 (of class [Ljava.lang.String;) 
at com.test.news.IO$$anonfun$1.apply(App.scala:58) 
at com.test.news.IO$$anonfun$1.apply(App.scala:57) 
at scala.collection.Iterator$$anon$11.next(Iterator.scala:409) 
at scala.collection.Iterator$class.foreach(Iterator.scala:893) 
at scala.collection.AbstractIterator.foreach(Iterator.scala:1336) 
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:59) 
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:104) 
at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:48) 
at scala.collection.TraversableOnce$class.to(TraversableOnce.scala:310) 
at scala.collection.AbstractIterator.to(Iterator.scala:1336) 
at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:302) 
at scala.collection.AbstractIterator.toBuffer(Iterator.scala:1336) 
at scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:289) 
at scala.collection.AbstractIterator.toArray(Iterator.scala:1336) 
at org.apache.spark.rdd.RDD$$anonfun$collect$1$$anonfun$13.apply(RDD.scala:912) 
at org.apache.spark.rdd.RDD$$anonfun$collect$1$$anonfun$13.apply(RDD.scala:912) 
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1916) 
at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1916) 
at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:70) 
at org.apache.spark.scheduler.Task.run(Task.scala:86) 
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at java.lang.Thread.run(Thread.java:745) 

ライン58は、ヴァル・アレイ(、info_sをしました)= s.split( "\ tの")で、私はこの方法を使用することはできませんか?私は混乱して〜助けている!

+2

ことつまり、入力行に、そのコード行で期待している2つの列の数よりも少ないか多い列があることを意味します。文字列 '" abcde "'と '" \ tb \ tc "'を入力としてスカラーシェルでその行を試してください。 – vanza

+0

@vanzaこれは答えであり、コメントではありません(特に現在の答えが与えられています)。 –

答えて

3

ありとして、Scalaでペアを開梱するための構文糖である:

val (id, info) = ("123", "word:123") 

は、しかし、配列内の要素は、パラメータの数と一致しない場合、これはsplit()によって返された配列のために動作しません。渡され、結果だけをキャプチャして、配列の値にアクセスするためにインデックスを使用するために変数を使用します。明らかに

sc.textFile("user_id.txt").map{ line => 
    val fields = line.split("\t") 
    val info = fields(1).split(",").map { kv => 
     val pairs = kv.split(":") 
     (pairs(0), pairs(1).toDouble) 
    }.toSeq 
    (fields(0), info) 
}.collect() 

# Array[(String, Seq[(String, Double)])] = Array((12334,WrappedArray((this,23.0), (word,21.0), (teacher,23.0)))) 

、私は私unapplyを認識していないです上記の方法をとったときに配列のthodが見つかりましたが、unapplyメソッドを使用するのが魅力的でした。ここでは、配列を展開して上記の方法と同じ考え方に従う代わりに、各行の最初の2つのフィールド。基本的にこの行を次の

、配列内の不要な要素を取り込むために_*を使用します。

val Array(k, v, _*) = Array(1, 2, 3, 4, 5) 
#k: Int = 1 
#v: Int = 2 

そして、上記の方法は、のように書き換えることができます。

sc.textFile("user_id.txt").map{ line => 
    val Array(id, info_s, _*) = line.split("\t") 
    val info = info_s.split(",").map { kv => 
     val Array(key, value, _*) = kv.split(":") 
     (key, value.toDouble) 
    }.toSeq 
    (id, info) 
}.collect() 

# Array[(String, Seq[(String, Double)])] = Array((12334,WrappedArray((this,23.0), (word,21.0), (teacher,23.0)))) 
+1

いいえ、 'val Array(id、info)= ...'のように、完全に合法です。問題は、配列内の要素の数です。 –

+0

私は@ Psidomの答えを試して、それは動作します。要素の数はどういう意味ですか? –

5

ライン5(val Array(k, v) = ...)上のあなたの構文を配列unapply methodを使用しています。あなたのケースでは

scala> val Array(k, v) = "1,2".split(",") 
k: String = 1 
v: String = 2 

scala> val Array(k, v) = "1,2,3".split(",") 
scala.MatchError: [Ljava.lang.String;@508dec2b (of class [Ljava.lang.String;) 

、これはおそらく、不正な形式の入力(複数:またはnone)によって引き起こされる:あなたは、抽出に供給するバインディングの数は、配列の長さと等しくない場合、一致エラーを取得することができます。抽出が有用かつ簡潔ですが、そのエラーメッセージが不可解なので、それはあなたが(任意のテキストファイルを読み込むように)あなたのマッチが正しいない場合は、もう少し詳細な構文を使うようにするとよいでしょう:

val (k, v) = kv.split(":") match { 
    case Array(f1, f2) => (f1, f2) 
    case Array(elems) => fatal("found invalid K/V pair: expected 2 elements, found ${elems.length}") 
} 
関連する問題