2013-10-07 63 views
1

比方說,我有一個看起來像這樣3元組序列:變換元組序列的列表在斯卡拉

Seq("m1" -> 1, "m2" -> 2) 
Seq("m3" -> 3, "m4" -> 4) 
Seq("m5" -> 5, "m2" -> 6) 

我要地圖對這些並返回看起來像下面的3個新的記錄:

Seq("m1" -> Some(1), "m2" -> Some(2), "m3" -> None, "m4" -> None, "m5" -> None) 
Seq("m1" -> None, "m2" -> None, "m3" -> Some(3), "m4" -> Some(4), "m5" -> None) 
Seq("m1" -> None, "m2" -> Some(6), "m3" -> None, "m4" -> None, "m5" -> Some(5)) 

,我正在尋找新的集合包含了不同的一組基礎上,相應的原始序列是否不包含元組從最初的名單中Some(v)None鍵和值的關鍵。

我設法從原來的列表中拔出鑰匙:

case class SiteReading(val site: String, val measures: Seq[(String, Double)]) 
val xs = getSomeSiteReadingsFromSomewhere() 
val keys = xs.flatMap(_.measures.map(t => t._1)).distinct 

我現在正計劃通過觀察兩個電流值和一套獨特的再次經歷整個列表,產生一個新的列表鍵。我想知道在這個集合框架中是否有一些漂亮的東西可以讓它變得更清潔,更容易處理?也許是免費的?

回答

1
val s1 = Seq("m1" -> 1, "m2" -> 2) 
val s2 = Seq("m3" -> 3, "m4" -> 4) 
val s3 = Seq("m5" -> 5, "m2" -> 6) 
val ss = Seq(s1, s2, s3) 
def foo(xss: Seq[Seq[(String,Int)]]): Seq[Seq[(String,Option[Int])]] = { 
    val keys = xss.flatMap(_.map(_._1)).toSet 
    xss.map{ xs => 
    val found = xs.map{ case (s,i) => (s, Some(i)) } 
    val missing = (keys diff xs.map(_._1).toSet).map(x => (x, None)).toSeq 
    (found ++ missing).sortBy(_._1) 
    } 
} 

scala> foo(ss).foreach(println) 
List((m1,Some(1)), (m2,Some(2)), (m3,None), (m4,None), (m5,None)) 
List((m1,None), (m2,None), (m3,Some(3)), (m4,Some(4)), (m5,None)) 
List((m1,None), (m2,Some(6)), (m3,None), (m4,None), (m5,Some(5))) 
+0

啊... ..差異這就是我一直在尋找對於。我確實有另一個想法可能會更好,不確定,我可能會嘗試。對於每一行創建的鑰匙,地圖一個地圖無(M1 - >無,2 - >無,等等),然後簡單地從原來的添加項目。 – andyczerwonka

+0

另外,你調用'toSet'而不是'distinct'。有特別的原因嗎? – andyczerwonka

+0

我也在下面使用我在上面評論中提到的想法回答了它。 – andyczerwonka

1

這裏是一個辦法。在鍵上映射並查詢每個映射以查看它是否包含鍵。

讓一組鍵來遍歷。

scala> val ms = (1 to 5).map(i => "m" + i) 
ms: scala.collection.immutable.IndexedSeq[String] = Vector(m1, m2, m3, m4, m5) 

三元組序列

scala> val s1 = Seq("m1" -> 1, "m2" -> 2).toMap 
s1: scala.collection.immutable.Map[String,Int] = Map(m1 -> 1, m2 -> 2) 

scala> val s2 = Seq("m3" -> 3, "m4" -> 4).toMap 
s2: scala.collection.immutable.Map[String,Int] = Map(m3 -> 3, m4 -> 4) 

scala> val s3 = Seq("m5" -> 5, "m2" -> 6).toMap 
s3: s3: scala.collection.immutable.Map[String,Int] = Map(m5 -> 5, m2 -> 6) 

mapSeq在每個Set,並嘗試得到鑰匙。

scala> ms.map(m => m -> s1.get(m)) 
res19: scala.collection.immutable.IndexedSeq[(String, Option[Int])] = 
Vector((m1,Some(1)), (m2,Some(2)), (m3,None), (m4,None), (m5,None)) 

scala> ms.map(m => m -> s2.get(m)) 
res20: scala.collection.immutable.IndexedSeq[(String, Option[Int])] = 
Vector((m1,None), (m2,None), (m3,Some(3)), (m4,Some(4)), (m5,None)) 

scala> ms.map(m => m -> s3.get(m)) 
res21: scala.collection.immutable.IndexedSeq[(String, Option[Int])] = 
Vector((m1,None), (m2,Some(6)), (m3,None), (m4,None), (m5,Some(5))) 
+0

我會做不同的映射Seqs到地圖在提前讓他們不能轉換爲每一個關鍵類似的東西:http://ideone.com/hZmIZw –

0

這裏是我的解決方案:

val s1 = Seq("m1" -> 1, "m2" -> 2) 
val s2 = Seq("m3" -> 3, "m4" -> 4) 
val s3 = Seq("m5" -> 5, "m2" -> 6) 

def process(ss: Seq[(String, Int)]*): Seq[Seq[(String, Option[Int])]] = { 
    val asMap = ss map (_.toMap) 
    val keys = asMap.flatMap(_.keys).sorted 
    for(m <- asMap) yield keys.map(k => k -> m.get(k)) 
} 

val Seq(r1, r2, r3) = process(s1, s2, s3) 

結果:

r1: Seq[(String, Option[Int])] = ArrayBuffer((m1,Some(1)), (m2,Some(2)), (m2,Some(2)), (m3,None), (m4,None), (m5,None)) 
r2: Seq[(String, Option[Int])] = ArrayBuffer((m1,None), (m2,None), (m2,None), (m3,Some(3)), (m4,Some(4)), (m5,None)) 
r3: Seq[(String, Option[Int])] = ArrayBuffer((m1,None), (m2,Some(6)), (m2,Some(6)), (m3,None), (m4,None), (m5,Some(5))) 
1

我喜歡雷克斯·科爾的答案。我評論說,這個解決方案也運行良好,可能更清晰簡明。

def denormalize(xss: Seq[Seq[(String, Double)]]): Seq[Map[String, Option[Double]]] = { 
    val keys = xss.flatMap(_.map(_._1)).distinct.sorted 
    val base = keys.map(_ -> None).toMap[String, Option[Double]] 
    xss.map(base ++ _.map(t => t._1 -> Option(t._2))) 
} 

它會同樣工作和一套。我不確定哪個表現更好。我可能會測試兩者。

+0

以'base'定義的映射之外,因爲它是恆定的。另外你我不認爲你必須在添加它之前將值轉換爲地圖。 –

+0

感謝@LuigiPlinge,我現在認爲這是一組最簡潔直接的方法。我猜測性能最高。 – andyczerwonka

+0

所以這可以被認爲是一個無點解決方案?你基本上只使用名稱來縮短代碼行,對嗎? (我想問的原因是我想知道是否可以將這個問題標記爲無點)。 –