2015-10-04 5 views
5

की तरह डेटा है: 2 स्तंभ से स्वयं की अनदेखी(तीखा) GroupBy foldLeft गुना में मान के अनुसार समूहबद्ध का उपयोग कर

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

अर्थ है, और बनाने: इसे बनाने के लिए

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

आवश्यकता एक अल्पविराम से अलग स्ट्रिंग में आराम करें। इसके टैब अलग डेटा

कोशिश की विविधताओं, लेकिन यकीन है कि 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 का उल्लेख करने के लिए कैसे तीखा 0.10.0 साथ स्केला 2.10 का उपयोग करना और 2.5.3 व्यापक नहीं। एक बदमाशी जवाब की आवश्यकता है। मुझे पता है कि स्कैला में डेटा का उपयोग कैसे करें। मैं बस सोच रहा हूं कि समूह के दौरान कॉलम को स्केलिंग में कैसे प्राप्त किया जाए और फ़िल्टर किए गए आउटपुट को प्राप्त करने के लिए सशर्त रूप से एक गुना बाएं या अन्य साधनों का उपयोग करें।

एक पूर्ण काम कर नमूने के लिए https://github.com/tgkprog/scaldingEx2/tree/master/Q1

+0

क्यों filer का उपयोग नहीं आत्म जोड़े और आईडी से तो समूह को हटाने के लिए? – roterl

+0

हां जो काम करता है, सिर्फ समूह को स्केल करने में कुछ चाहिए था, इसलिए उसी चरण में फ़िल्टर कर सकते हैं – tgkprog

उत्तर

1

देख बस एक groupBy और एक map आप क्या चाहते हैं पूरा करने के लिए पर्याप्त होना चाहिए।

// 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 scalding में एक समाधान की जरूरत है। – tgkprog

1

मान लें pid| recom-pid > temp.txt और इतने

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

हम tuples में xs कनवर्ट करते हैं, इस

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)) 
पहला तत्व द्वारा

और समूह की तरह,

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

फिर हम मैप किया हटाने पहचान tuples, जो सुनिश्चित करता है हमेशा मानचित्र में एक प्रविष्टि, जहां एक खाली सरणी इंगित करती है केवल पहचान टुपल थी (जैसे। 3|3 की अनूठी घटना, 3 -> Array()) करने के लिए नेतृत्व करेंगे

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 scalding में एक समाधान की जरूरत है। – tgkprog

1

Asssuming अपने स्ट्रिंग इनपुट आप रिटर्न कि एक मानचित्र सही है [स्ट्रिंग, सरणी [स्ट्रिंग]]

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

के बजाय groupBy और फिर foldLeft, केवल foldLeft का उपयोग करें।
यहाँ एक समाधान स्केला संग्रह का उपयोग कर रहा है, लेकिन यह 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 पाइप का सदस्य नहीं है। ऐसा लगता है कि दस्तावेज़ों में एक शीर्षक के रूप में है लेकिन reducers के तहत है – tgkprog

संबंधित मुद्दे