2

我的意图很简单:从用户对象列表中获取电子邮件的逗号分隔值。我在 Java 中使用 for 循环和 if else 条件完成了此操作。

现在我想在 Scala 中做到这一点,所以我尝试了这个。

case class User(name: String, email: String)

val userList = List(User("aaa", "aaa@aaa.com"),
                    User("bbb", "bbb@bbb.com"),
                    User("ccc", "ccc@ccc.com"))

现在

val mailIds = userList.foldLeft(""){(a: String, b: User) => ( b.email+","+a) } 

ccc@ccc.com,bbb@bbb.com,aaa@aaa.com,

(注意最后的逗号。)

val mailids = userList.map(x => x.email).reduceLeft(_+","+_)

aaa@aaa.com,bbb@bbb.com,ccc@ccc.com

我试过只reduceLeft这样 使用

val emailids = userList.reduceLeft((emails: String, user: User) => emails+", "+user.email)

但它会引发编译错误

type mismatch;  found   : (String, User) => java.lang.String  required: (java.io.Serializable, User) => java.io.Serializable

那么,在上述情况下是否有更好的使用方法?reduceLeftmap

4

2 回答 2

2

不,累加器reduceLeftfoldLeft集合的第一个元素。在您的情况下,第一个元素是 aUser并且您必须为迭代的下一步传递相同类型的参数。这就是你得到类型不匹配的原因。
您可以在惰性集合中执行映射并像下面这样减少它:

val mailIds = userList.view map (_.email) reduceLeft (_ + "," + _)

这将使您aaa@aaa.com,bbb@bbb.com,ccc@ccc.com无需创建第二个集合。Jessie Eichar 为此写了一个非常好的教程

编辑

没有惰性集合的方法是通过以下方式删除最后一个逗号:

val rawMailIds = userList.foldLeft("")((acc, elem) => acc + elem.email + ",")
val mailIds = rawMailIds.substring(0, rawMailIds.length - 1)
于 2012-05-08T11:32:13.550 回答
0

为什么不坚持 map 和 reduce 的结合呢?无论如何,您的问题是您reduceLeft唯一的版本需要有一个字符串作为其初始值。

于 2012-05-08T11:13:50.717 回答