2015-10-04 9 views
5

の値でグループを使用してGROUPBY foldLeftを(火傷)のようなデータがあります:

pid recom-pid 
1 1 
1 2 
1 3 
2 1 
2 2 
2 4 
2 5 

はそれを行う必要があります。

pid, recommendations 
1 2,3 
2 1,4,5 

意味は2列目からの自己を無視し、そして作りますコンマ区切りの文字列にしてください。そのタブ区切りデータ

はのバリエーションを試してみましたが、火傷0.10.0とScalaの2.10を使用して2.5.3をカスケード接続foldLeft

.groupBy('productId) {  
    _.foldLeft(('prodReco) -> 'prodsR)("") { 
    (s: String, s2: String) => 
     { 
     println(" s " + s + ", s2 :" + s2 + "; pid :" + productId + ".") 
     if (productId.equals(s2)) { 
      s 
     } else { 
      s + "," + s2; 
     } 
     } 
    } 
} 

でのProductIDを参照する方法がわかりません。怒りの答えが必要です。私はスカラーでデータを操作する方法を知っています。私はちょうど鱗を引くことでグループの中で列を保持する方法を疑問に思っているし、条件付きで折り畳みを左にするなどの方法でフィルタリングされた出力を得る方法を使用します。完全に動作するサンプルについて

ちょうど groupBymapはあなたが望むものを達成するために十分なはずです

+0

なぜidで自己のペアと、グループを削除するには、ファイラーを使用していませんか? – roterl

+0

はい、うまく動作します。ただグループをスケーリングするときに何かを欲しかったので、同じフェーズでフィルタリングすることができます – tgkprog

答えて

1

https://github.com/tgkprog/scaldingEx2/tree/master/Q1を参照してください。

// Input data formatted as a list of tuples. 
val tt = Seq((1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 4), (2, 5)) 

tt 
    .groupBy(_._1) // Map(2 -> List((2, 1), ...), 1 -> List((1, 1), ...)) 
    .toSeq // for easier mapping 
    .map({ 
    case (pid, recomPids) => { 
     val pids = recomPids.collect({ 
     case recomPid if recomPid._2 != pid => recomPid._2 
     }) 
     (pid, pids) 
    } 
    }) // List((2, List(1, 4, 5)), (1, List(2, 3))) 

入出力フォームを単純化して、コレクションを適切な形式にすることに専念しました。

+0

いいですが使用できません。私はAPIを急ぐことで解決策が必要です。 – tgkprog

1

私たちは、その後、我々は、マッピングされたアイデンティティを削除し、最初の要素によって、この

val pairs = for (Array(pid, recom) <- xs) yield (pid,recom) 
Array((1,1), (1,2), (1,3), (2,1), (2,2), (2,4), (2,5)) 

とグループのように、タプルにxsを変換

val g = pairs.groupBy(_._1) 
Map(2 -> Array((2,1), (2,2), (2,4), (2,5)), 1 -> Array((1,1), (1,2), (1,3))) 

pid| recom-pid > temp.txtので

import scala.io.Source 
val xs = Source.fromFile("temp.txt").getLines.toArray.map(_.split("\\|")) 

を想定タプル常にマップ内のエントリ。空の配列はアイデンティティタプルのみが存在することを示します。 3|3のユニークな発生は3 -> Array()につながる)、あなたの文字列の入力をAsssuming

val res = g.mapValues(_.filter { case (a,b) => a != b }) 
Map(2 -> Array((2,1), (2,4), (2,5)), 1 -> Array((1,2), (1,3))) 
+0

いいですが使えません。私はAPIを急ぐことで解決策が必要です。 – tgkprog

1

は、あなたのマップ[文字列、配列[文字列]]

s.split('\n') 
.map(_.split("\\|")) 
.groupBy(_(0)) 
.mapValues(_.flatten) 
.transform {case (k, v) ⇒ v.filter(_ != k)} 
2

代わりのgroupBy、その後foldLeftを返すことが正しいですちょうどfoldLeftを使用してください。ここ
はScalaのコレクションを使用したソリューションですが、それはscalading as wellを使って作品をする必要があります

val source = List((1,1), (1,2), (1,3), (2,1), (2,2), (2,4), (2,5))                     
source.foldLeft(Map[Int, List[Int]]())((m,e) =>         
    if (e._1 == e._2) m else m + (e._1 -> (e._2 :: m.getOrElse(e._1, List())))) 
+0

foldLeftはPipeのメンバーではありません。見出しのような文書のように見えるが、還元剤の下にある – tgkprog