2011-05-09 18 views
1

我希望創建一個按名稱鍵入的Map,其中包含具有該名稱的事物的計數。我有一個名稱列表,其中可能包含多個具有相同名稱的項目。編碼這樣我得到一個錯誤「類型不匹配;發現:字符串要求:(字符串,整數)」:爲什麼我必須明確指出Tuple2(a,b)能夠在foldLeft中使用Map add?

//variation 0, produces error 
(Map[String, Int]() /: entries)((r, c) => { r + (c.name, if (r.contains(c.name)) (c.name) + 1 else 1) }) 

這讓我困惑,因爲我雖然(A,B)是一個Tuple2,因此適用於使用地圖添加。以下任一變體均可按預期工作:

//variation 1, works 
(Map[String, Int]() /: entries)((r, c) => { r + Tuple2(c.name, if (r.contains(c.name)) (c.name) + 1 else 1) }) 
//variation 2, works 
(Map[String, Int]() /: entries)((r, c) => { 
    val e = (c.name, if (r.contains(c.name)) (c.name) + 1 else 1) }) 
    r + e 

我不清楚爲什麼我的第一個版本出現問題;任何人都可以建議。我正在使用Scala-IDE 2.0.0 beta 2來編輯源代碼;該錯誤來自Eclipse Problems窗口。

+3

條目groupBy(_.name)mapValues(_.length)// SO正在吃我的下劃線 – 2011-05-09 19:25:05

+0

根據'entries'類型和長度的不同,這可能會導致很多糟糕的結果。 – 2011-05-09 20:04:35

+0

我認爲這將永遠是一個常數因子較慢。這取決於你的域名仍然可以被認爲是「很多」。 – 2011-05-09 22:45:44

回答

3

當傳遞一個元組的參數與運營商所使用的符號,比如你+方法的方法,你應該使用雙括號:

(Map[String, Int]() /: entries)((r, c) => { r + ((c.name, r.get(c.name).map(_ + 1).getOrElse(1))) }) 

我也改變了Int的計算,這看起來很滑稽在你的榜樣......

+0

OK,所以如果我遵循它認爲'r +(a,b)'意思是「調用傳遞給'a,b'的+方法,因此'r +((a,b))'意味着」調用(a,b)'(例如Tuple2(a,b))中的加號方法。雖然每天都有點煩人,但確實有道理;謝謝 編輯:並感謝提醒getOrElse ;從Java和我轉移過來仍然傾向於認爲?:=> if/else對於getOrElse更有意義的情況。 – S42 2011-05-09 20:21:54

+1

@ S42是的,你明白了。如果你不喜歡雙括號,你可以使用[阿列克謝的建議](http://stackoverflow.com/questions/5940822/why-do-i-have-to-explicitly-state-tuple2a-b-to-使用map-add-in-a-fol/5941166#5941166)使用「箭頭」 - >'來創建元組。 – 2011-05-09 20:47:46

1
r + (c.name, if (r.contains(c.name)) (c.name) + 1 else 1) 

被解析爲

r.+(c.name, if (r.contains(c.name)) (c.name) + 1 else 1) 

因此,編譯器在Map上查找帶有2個參數的+方法,但未找到它。形式我更喜歡雙括號(如讓 - 菲利普·佩萊建議)是

r + (c.name -> if (r.contains(c.name)) (c.name) + 1 else 1) 

UPDATE:

如果顆粒是正確的,最好是寫

r + (c.name -> r.getOrElse(c.name, 0) + 1) 

(當然詹姆斯Iry的解決方案更好地表達了同樣的意圖)。

+0

但是'(c.name)+ 1'不是'Int' ...我認爲OP代表'r(c.name)+ 1'。然後,查找會執行兩次 - 一次用於「包含」,一次用於「應用」。 – 2011-05-09 18:57:55

3

因爲+用於連接字符串與字符串的東西。在這種情況下,括號不是意味着一個元組,而是指一個參數。

斯卡拉已經使用+其他的東西,導致各種各樣的問題,就像你提到的那樣。

+替換爲updated,或者使用->而不是,

相關問題