2015-02-28 25 views
13

Ben fonksiyonel programlama diline Newbie ve ben bir Üniversite projesi için Scala bunu öğreniyorum.Scala - Array Array [dize] dönüştürmek [Çift]

Bu basit gibi görünebilir, ama bu ya bunu yapmanın basit bir yolu için çevrimiçi yeterli yardım bulamıyorum - nasıl [Çift] Array [Dize] bir Array dönüştürebilirsiniz? REPL içine okunduğunda String değerleri olarak yorumlanabilen bir CSV dosyası var (her satırın bir tamsayı ve dize değerleri karışımı vardır). Bu, bir dizi Array [String] döndürecektir. Diziyi homojen hale getirmek için dizi değerlerini çift/int değerleriyle kodlamak istiyorum. Bunu yapmanın basit bir yolu var mı? Herhangi bir rehberlik çok takdir edilecektir. Şu ana kadar ne yaptın

geçerli:

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

Ve CSV dosyasındaki her satır dönüştürmek için:

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

    return items.toArray 
} 

(dize [] olarak iade) Her satırın biçimi böyledir çift ​​dizi içine, ben sadece bir psuedo tanımı taslak var yani:

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 
} 

Herhangi bir fikir kabul edilir. Zaman ayırdığın için teşekkürler.

Hepiniz çevrilemeyen dizeleri 1.0 yedeği ile iki katına tüm dizeleri dönüştürmek demek

cevap

22
Muhtemelen toDouble birlikte map kullanmak istediğiniz

: daha kısaca

values.map(x => x.toDouble) 

Veya:

values.map(_.toDouble) 

Ve olmayan çift dizeleri yedeği için, sen (scala.util olarak) Try monad değerlendirebilirsiniz:

Her satırı da desen eşleştirme yapabileceği, nasıl görüneceğini biliyorsanız
values.map(x => Try(x.toDouble).getOrElse(1.0)) 

: DaunnC yorumuyla @ üzerinde Genişleyen

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

getOrElse ifadesi veya desen eşleşmesi, benim için en iyisini çalışır. Ancak, her zaman sadece 1.0'a geri dönmek yerine buna sayaç ekleyip ekleyemeyeceğimi bilmek istedim. Range'i (n1, n2) duydum ama aradığım şey değil, bir sayaç arıyorum çünkü item1 ve item2'nin farklı (belki de ardışık) sayılara sahip olmasını istiyorum. Mümkün mü? –

+0

Elbette - "getOrElse" maddesinde istediğiniz mantığı koyabilirsiniz. Örneğin, bir yineleyici 'val fallbackIterator = Iterator.from (0)' yapabilir ve 'getOrElse (fallbackIterator.next)' işlevini kullanabilirsiniz, böylece 'getOrElse' için her bir sonraki çağrı, geri dönüş değerini artırır. –

+0

Ben bunu deneyin monad: scala.util içinde bilmiyordum. v güzel cevap burada. – javadba

3

? Yani şöyle olacaktır:

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

daha da önemlisi – dhg

+0

@dhg ve uyarı derleyici önlemek için 'java.lang.NumberFormatException' yakalamak için: Burada

Mauricio Linhares ait deneyin nezaketinde birtakım bilgiler verilmiştir ve dahili VM hataları. derleyici uyarısı ... – rightfold

+0

, evet, ama o? –

3

, Sonucun bu ve desen maçı yapmak Try yardımcı programını kullanabilirsiniz Bu olanak sağlar

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 
} 

hep ya birolan Try sonucu, üzerine desen maçı için: böylece get numaralı telefondan veya Option daki sonucu sarma önleyebilirsiniz get arayabilir veya başka şekilde sonuçlarınızı sarmak zorunda kalmadanveya Failure. OOM gibi ölümcül durumları yakalamak önlemek için: Daha iyi https://mauricio.github.io/2014/02/17/scala-either-try-and-the-m-word.html

+0

kopyala/benim ana yöntem haline kodunuzu yapıştırılan ve bu O/P olsun: Başarı (5.0) Başarı (1.0) Başarı (8.5) Başarı (10.0) Başarısızlık (java.lang.NumberFormatException: Giriş dizesi için: "item1") Hata (java.lang.NumberFormatException: Girdi dizesi için: "item2") –

+0

Ah, bunun nedeni son haritayı vermemesidir. Cevabımı güncelledim. –