2010-09-03 7 views
5

उदाहरण के लिए, एक निम्न फ़ाइल से:स्कैला में, मुख्य मूल्यों की एक जोड़ी से सीएसवी में एक elemein कैसे खोजें?

 
Name,Surname,E-mail 
John,Smith,[email protected] 
Nancy,Smith,[email protected] 
Jane,Doe,[email protected] 
John,Doe,[email protected] 

कैसे मैं जॉन डो की ई-मेल एड्रेस मिलता है?

मैं अब निम्नलिखित कोड का उपयोग, लेकिन अब सिर्फ एक ही चाबी क्षेत्र निर्दिष्ट कर सकते हैं:

 

val src = Source.fromFile(file) 
val iter = src.getLines().drop(1).map(_.split(",")) 
var quote = "" 
iter.find(_(1) == "Doe" ) foreach (a => println(a(2))) 
src.close() 
 

मैं लेखन की कोशिश की है "iter.find (_ (0) ==" जॉन "& & _ (1) == "डो") ", लेकिन यह एक त्रुटि उत्पन्न करता है जिसमें कहा गया है कि केवल एक पैरामीटर अपेक्षित है (कोष्ठक की अतिरिक्त जोड़ी में स्थिति को संलग्न करने से मदद नहीं मिलती है)।

+0

यदि यह वास्तव में एक CSV फ़ाइल है, तो StringOps.split (",") का उपयोग गलत है और उन मामलों से निपट नहीं है जहां या तो अल्पविराम (,) और/या एक डबल कोट (") का हिस्सा हैं एम्बेडेड वैल्यू। मैंने इसे अपने स्टैक ओवरफ्लो उत्तर में यहां संबोधित किया है: http://stackoverflow.com/a/32488453/501113 – chaotic3quilibrium

उत्तर

5

लैम्ब्डा के पैरामीटर के लिए प्लेसहोल्डर के रूप में अंडरस्कोर आपके विचार से काम नहीं करता है।

a => println(a) 
// is equivalent to 
println(_) 

(a,b) => a + b 
// is equivalent to 
_ + _ 

a => a + a 
// is not equivalent to 
_ + _ 

यही है, पहला अंडरस्कोर पहला पैरामीटर है और दूसरे का मतलब दूसरा पैरामीटर है और इसी तरह। तो यही कारण है कि आप जो त्रुटि देख रहे हैं - आप दो अंडरस्कोर का उपयोग कर रहे हैं लेकिन केवल एक पैरामीटर है।

iter.find(a=> a(0) == "John" && a(1) == "Doe") 
1

आप Regex का उपयोग कर सकते हैं::

scala> def getRegex(v1: String, v2: String) = (v1 + "," + v2 +",(\\S+)").r 
getRegex: (v1: String,v2: String)scala.util.matching.Regex 

scala> val src = """John,Smith,[email protected] 
    | Nancy,Smith,[email protected] 
    | Jane,Doe,[email protected] 
    | John,Doe,[email protected] 
    | """ 
src: java.lang.String = 
John,Smith,[email protected] 
Nancy,Smith,[email protected] 
Jane,Doe,[email protected] 
John,Doe,[email protected] 


scala> val MAIL = getRegex("John","Doe") 
MAIL: scala.util.matching.Regex = John,Doe,(\S+) 

scala> val itr = src.lines 
itr: Iterator[String] = non-empty iterator 

scala> for(MAIL(address) <- itr) println(address) 
[email protected] 

scala> 
+1

और आप MAIL.findAllIn (src) का भी उपयोग कर सकते हैं। – Eastsun

0

तुम भी एक for समझ में split के परिणाम पर एक पैटर्न मैच फिक्स कर सकता है स्पष्ट संस्करण का उपयोग करने के लिए है।

val firstName = "John" 
val surName = "Doe" 
val emails = for { 
    Array(`firstName`, `surName`, email) <- 
    src.getLines().drop(1) map { _ split ',' } 
} yield { email } 

println(emails.mkString(",")) 

नोट पैटर्न में बैकटिक: इसका मतलब यह है कि हम एक नया वेरिएबल मिलान कुछ भी शुरू करने और val firstname पीछा करने के बजाय firstName के मूल्य पर मेल खाते हैं।

+0

स्ट्रिंगऑप्स.split (",") का उपयोग करना है ग़लत है और उन मामलों से निपट नहीं आता है जहां या तो अल्पविराम (,) और/या एक डबल कोट (") एम्बेडेड मान का हिस्सा हैं। मैंने इसे अपने स्टैक ओवरफ्लो उत्तर में यहां संबोधित किया: stackoverflow.com/a/32488453/501113 – chaotic3quilibrium

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