2012-04-08 125 views
1

我有一個List(List("aba, 4"), List("baa, 2")),我想將其轉換成圖:如何將List(List [String])轉換爲Map [String,Int]?

val map : Map[String, Int] = Map("aba" -> 4, "baa" -> 2) 

什麼是存檔的最佳方式?

UPDATE:

我做一個數據庫查詢檢索數據: VAL(_,MYDATA的)= DB.runQuery(...)

這會返回一個對,但我只感興趣在第二部分,這給了我:

myData: List[List[String]] = List(List(Hello, 19), List(World, 14), List(Foo, 13), List(Bar, 13), List(Bar, 12), List(Baz, 12), List(Baz, 11), ...) 

回答

1

我的看法:

List(List("aba, 4"), List("baa, 2")) map {_.head} map {itemList => itemList split ",\\s*"} map {itemArr => (itemArr(0), itemArr(1).toInt)} toMap 

步驟:

List(List("aba, 4"), List("baa, 2")). 
    map(_.head).         //List("aba, 4", "baa, 2") 
    map(itemList => itemList split ",\\s*").  //List(Array("aba", "4"), Array("baa", "2")) 
    map(itemArr => (itemArr(0), itemArr(1).toInt)). //List(("aba", 4), ("baa", 2)) 
    toMap           //Map("aba" -> 4, "baa" -> 2) 

你輸入數據結構是一個有點尷尬,所以我不認爲你可以對其進行優化/縮短它的任何進一步。

+0

它與小提供的清單一起使用。但是,當我嘗試這與數據列表我有我得到一個java.lang.ArrayIndexOutOfBoundsException:1 ...我可以防止它以某種方式嗎? – user1243091 2012-04-08 11:53:52

+0

@ user1243091:列表的大小在這裏並不重要。我猜這個問題是'(itemArr(0),itemArr(1).toInt)'這意味着你的一些輸入字符串不會跟隨''string,int「'模式。嘗試在你的輸入上運行:'List(List(「aba,4」),List(「baa,2」))map {_head} map {itemList => itemList split,\\ s *「} filterNot {_.size == 2}' - 它應該不**返回任何東西 – 2012-04-08 11:58:04

+0

它返回一些東西,實際上是我的List [List [String]]中的所有東西。這很有趣......我不明白。在我的列表[字符串]中的條目真的看起來像提供的示例數據... – user1243091 2012-04-08 12:38:50

1
List(List("aba, 4"), List("baa, 2")). 
    flatten.  //get rid of those weird inner Lists 
    map {s=> 
    //split into key and value 
    //Array extractor guarantees we get exactly 2 matches 
    val Array(k,v) = s.split(","); 
    //make a tuple out of the splits 
    (k, v.trim.toInt)}. 
    toMap // turns an collection of tuples into a map 
+0

這給了我一個scala.MatchError:[Ljava.lang.String; @ 6bf4d04a(類[Ljava.lang.String;) \t在$ anonfun $ 1.apply(:23) \t at $ anonfun $ 1.apply(:20) – user1243091 2012-04-08 12:41:11

+0

給我們提供您正在使用的數據 – 2012-04-08 14:18:26

+0

我在問題中提供了一些數據。查看更新部分... – user1243091 2012-04-08 14:54:31

4

另一種看法:

List(List("aba, 4"), List("baa, 2")). 
    flatten.par.collect(
    _.split(",").toList match { 
     case k :: v :: Nil => (k, v.trim.toInt) 
    }).toMap 

差異對其他答案:

  • 使用.par並行創建對,這使我們能夠從多個核心獲利。
  • 使用collectPartialFunction忽略字符串的形式是不是「鍵,值」

編輯:.par確實not destroy the order作爲應答狀態之前。列表處理的執行順序不能保證,所以函數應該是無副作用的(或者副作用不應該關心排序)。

+0

有一點需要注意:'.par'僅適用於2.9以上版本的Scala。 (你確定,'.par'破壞了訂單嗎?) – 2012-04-08 13:21:46

+0

感謝您發現這一點。我搞砸了,中間處理是無序的(f.ex.' println'調用),但結果值將再次以相同的順序拼湊在一起。 – Frank 2012-04-08 15:58:31

8
scala> val pat = """\((.*),\s*(.*)\)""".r 
pat: scala.util.matching.Regex = \((.*),\s*(.*)\) 

scala> list.flatten.map{case pat(k, v) => k -> v.toInt }.toMap 
res1: scala.collection.immutable.Map[String,Int] = Map(aba -> 4, baa -> 2) 
+0

+1,夥計們,這是一個非常非常好的答案。有一件事,需要,「k - > v.toInt」匹配問題 – virtualeyes 2012-04-08 14:54:00

+0

@virtualeyes指定的Map [String,Int],噢,我沒有看到'Int'類型。建議修正。 – huynhjl 2012-04-08 15:32:06

相關問題