为什么我必须明确声明 Tuple2(a, b) 才能在 FoldLeft 中使用 Map add ?

发布于 2024-11-05 20:09:20 字数 759 浏览 3 评论 0原文

我希望创建一个按名称键控的地图,其中包含具有该名称的事物的计数。我有一个带有名称的事物列表,其中可能包含多个具有相同名称的项目。像这样编码,我得到一个错误“类型不匹配;发现:需要字符串:(String, Int)”:

//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,因此适合与 Map add 一起使用。以下任一变体均按预期工作:

//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 窗口。

I wish to create a Map keyed by name containing the count of things with that name. I have a list of the things with name, which may contain more than one item with the same name. Coded like this I get an error "type mismatch; found : String required: (String, Int)":

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

This confuses me as I though (a, b) was a Tuple2 and therefore suitable for use with Map add. Either of the following variations works as expected:

//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

I'm unclear on why there is a problem with my first version; can anyone advise. I am using Scala-IDE 2.0.0 beta 2 to edit the source; the error is from the Eclipse Problems window.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

栀梦 2024-11-12 20:09:20

当将单个元组参数传递给与运算符表示法一起使用的方法(例如 + 方法)时,您应该使用双括号:

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

我还更改了 Int 的计算,在你的例子中看起来很有趣......

When passing a single tuple argument to a method used with operator notation, like your + method, you should use double parentheses:

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

I've also changed the computation of the Int, which looks funny in your example…

浅忆流年 2024-11-12 20:09:20

因为 + 用于连接字符串和字符串。在这种情况下,括号并不表示元组,而是表示参数。

Scala 使用 + 来做其他事情,这导致了各种各样的问题,就像你提到的那样。

+ 替换为 updated,或使用 -> 代替 ,

Because + is used to concatenate strings stuff with strings. In this case, parenthesis are not being taken to mean a tuple, but to mean a parameter.

Scala has used + for other stuff, which resulted in all sorts of problems, just like the one you mention.

Replace + with updated, or use -> instead of ,.

独享拥抱 2024-11-12 20:09:20
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 个参数+ 方法,但没有找到。相对于双括号(正如 Jean-Philippe Pellet 所建议的那样),我更喜欢的形式是

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

UPDATE:

如果 Pellet 是正确的,那么最好这样写

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

(当然 James Iry 的解决方案更好地表达了相同的意图)。

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

is parsed as

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

So the compiler looks for a + method with 2 arguments on Map and doesn't find it. The form I prefer over double parentheses (as Jean-Philippe Pellet suggests) is

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

UPDATE:

if Pellet is correct, it's better to write

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

(and of course James Iry's solution expresses the same intent even better).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文