2015-02-28 8 views
13

मैं कार्यात्मक प्रोग्रामिंग भाषा के लिए नौसिखिया हूं और मैं इसे विश्वविद्यालय परियोजना के लिए स्कैला में सीख रहा हूं।स्कैला - ऐरे [स्ट्रिंग] को ऐरे में परिवर्तित करें [डबल]

यह आसान प्रतीत हो सकता है, लेकिन मैं इस के लिए पर्याप्त सहायता पाने में असमर्थ हूं या ऐसा करने का एक सीधा तरीका - मैं एक ऐरे [स्ट्रिंग] को ऐरे [डबल] में कैसे परिवर्तित कर सकता हूं? मेरे पास एक सीएसवी फ़ाइल है जो, जब आरईपीएल में पढ़ा जाता है तो स्ट्रिंग मानों के रूप में व्याख्या की जाती है (फ़ाइल की प्रत्येक पंक्ति में पूर्णांक और स्ट्रिंग मानों का मिश्रण होता है) जो एक प्रकार ऐरे [स्ट्रिंग] लौटाएगा। सरणी को सजातीय बनाने के लिए मैं स्ट्रिंग मानों को दोहरी/int मानों के साथ एरे [डबल] वापस करने के लिए एन्कोड करना चाहता हूं। क्या ऐसा करने का एक सीधा तरीका है? किसी भी मार्गदर्शन की सराहना की जाएगी।

मैं अब तक क्या किया है:

def retrieveExamplesFromFile(fileName : String) : Array[Array[String]] = { 
    val items = for { 
    line <- Source.fromFile(fileName).getLines() 
    entries = line.split(",") 
    } yield entries 

    return items.toArray 
} 

प्रत्येक पंक्ति (String [] के रूप में वापस) के प्रारूप इतना है:

[[1.0, 2.0, item1], [5, 8.9, item2],....] 

और CSV फ़ाइल में प्रत्येक पंक्ति कन्वर्ट करने के लिए डबल सरणी में, मेरे पास केवल एक psuedo परिभाषा तैयार की गई है:

def generateNumbersForStringValues(values : Array[String]) : Array[Double] = { 
val line = for(item <- values) 
{ 
    //correct way? 
    item.replace("item1", "1.0") 
    item.replace("item2", "1.0")  
} 
return //unable to typecast/convert 
} 

किसी भी विचार का स्वागत है। आपके समय के लिए शुक्रिया।

उत्तर

22

आप शायद toDouble के साथ map उपयोग करना चाहते हैं:

values.map(x => x.toDouble) 

या अधिक संक्षेप में:

values.map(_.toDouble) 

और गैर डबल तार के लिए वापस आने के लिए, आप Try मोनैड (scala.util में) का उपयोग करने पर विचार कर सकते हैं:

values.map(x => Try(x.toDouble).getOrElse(1.0)) 

आप जानते हैं कि प्रत्येक पंक्ति की तरह, आप भी पैटर्न मिलान कर सकता है लगेगा:

values map { 
    case Array(a, b, c) => Array(a.toDouble, b.toDouble, 1.0) 
} 
+0

GetOrElse कथन या पैटर्न मिलान मेरे लिए सबसे अच्छा काम करता है। हालांकि, मैं जानना चाहता था कि क्या मैं हर समय सिर्फ 1.0 लौटने के बजाय इसका सामना कर सकता हूं? मैंने रेंज (एन 1, एन 2) के बारे में सुना है, लेकिन यह वह नहीं है जिसे मैं ढूंढ रहा हूं, मैं एक काउंटर की तलाश में हूं क्योंकि मैं item1 और item2 को अलग-अलग (शायद लगातार) संख्याएं चाहता हूं। क्या यह संभव है? –

+0

निश्चित - आप 'getOrElse' खंड में जो भी तर्क चाहते हैं उसे डाल सकते हैं। उदाहरण के लिए, आप एक इटरेटर 'वैल फॉलबैकइटरेटर = इटरेटर.फॉम (0)' बना सकते हैं, और उसके बाद 'getOrElse (fallbackIterator.next)' का उपयोग करें, ताकि प्रत्येक getive कॉल 'getOrElse' में फॉलबैक वैल्यू बढ़ेगा। –

+0

मैं उस मोनाद की कोशिश कर रहा था: scala.util में नहीं पता था। वी यहाँ सुंदर जवाब। – javadba

3

क्या आप सभी तारों को सभी अपरिवर्तनीय तारों के लिए 1.0 पर फ़ॉलबैक के साथ डबल करने के लिए परिवर्तित करना चाहते हैं? यही कारण है कि होगा:

val x = Array(
    Array("1.0", "2.0", "item1"), 
    Array("5", "8.9", "item2")) 

x.map(_.map { y => 
    try { 
    y.toDouble 
    } catch { 
    case _: NumberFormatException => 1.0 
    } 
}) 
+1

बेहतर 'java.lang.NumberFormatException' को पकड़ने के लिए संकलक – dhg

+0

@dhg और चेतावनी अधिक महत्वपूर्ण बात से बचने के लिए: OOM की तरह घातक अपवाद को पकड़ने से बचने के लिए

यहाँ मौरिसियो लिन्हारेस की कोशिश शिष्टाचार पर कुछ और जानकारी है और आंतरिक वीएम त्रुटियों। – rightfold

+0

@ райтфолд, हाँ, लेकिन यही कारण है कि संकलक चेतावनी ... –

3

@ DaunnC की टिप्पणी पर विस्तार, आप परिणाम पर इस और पैटर्न मैच करने के लिए Try उपयोगिता का उपयोग कर सकते हैं

import scala.util.{Try, Success, Failure} 

def main = { 
    val maybeDoubles = Array("5", "1.0", "8.5", "10.0", "item1", "item2") 

    val convertDoubles = maybeDoubles.map { x => 
    Try(x.toDouble) 
    } 

    val convertedArray = convertDoubles.map { 
    _ match { 
     case Success(res) => res 
     case Failure(f) => 1.0 
    } 
    } 

    convertedArray 
} 

यह आपको अनुमति देता है Try का परिणाम है, जो हमेशा या तो एकहै पर पैटर्न मैच के लिए: तो तुम get बुला या एक Option में अपने परिणाम लपेटकर से बच सकते हैंया Failure, get पर कॉल किए बिना या अन्यथा अपने परिणाम लपेटें। https://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html

+0

अपने कोड को मेरी मुख्य विधि में कॉपी/पेस्ट किया गया है और मुझे यह ओ/पी प्राप्त होता है: सफलता (5.0) सफलता (1.0) सफलता (8.5) सफलता (10.0) विफलता (java.lang.NumberFormatException: इनपुट स्ट्रिंग के लिए: "item1") असफलता (java.lang.NumberFormatException: इनपुट स्ट्रिंग के लिए: "item2") –

+0

आह, ऐसा इसलिए होगा क्योंकि यह अंतिम मानचित्र नहीं दे रहा था। मैंने अपना जवाब अपडेट किया। –

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