Scala中的foreach()返回一个Seq。如何到达物品?

时间:2018-11-24 03:56:52

标签: scala

我正在尝试将列表的每个元素添加到MutableSet。

节俭:

Obj {
  list<Tag> myList;
}

enum Tag {
  ...
}

斯卡拉:

val uniqueTags = Set[Tag]()
// obj is of type Obj defined in the thrift above
obj.flatMap(_.myList).foreach(uniqueTags += _)

但是,编译器表示我正在尝试添加Seq[Tag]而不是Tag。如何到达由Seq表示的元素?

此外,我敢肯定还有另一种直接用列表初始化Set的方法。我尝试了obj.flatMap(_.myList).toSet()Set[Tag](obj.flatMap(_.myList))),但是都没有。

2 个答案:

答案 0 :(得分:3)

您无需反复查找唯一的scala does that for you with toSet

使用toSet的示例:

scala> case class Obj(myList: List[String])
defined class Obj

scala> val obj = Option(Obj(myList = List("metal", "rock", "prog", "pop", "pop")))
obj: Option[Obj] = Some(Obj(List(metal, rock, prog, pop, pop)))

现在,要获取唯一标签,

scala> val uniqueTags = obj.map(_.myList).getOrElse(List.empty[String]).toSet
uniqueTags: scala.collection.immutable.Set[String] = Set(metal, rock, prog, pop)
不建议使用

foreach对fp世界中的内容进行突变。另一种方法是使用accumulator pattern-foldLeft

scala> import scala.collection.immutable.Set
import scala.collection.immutable.Set

scala> obj.map(_.myList).getOrElse(List.empty[String]).foldLeft(Set[String]()){ case (s, e) => s + e }
res15: scala.collection.immutable.Set[String] = Set(metal, rock, prog, pop)

可变的方法是在执行操作时使用forach(不推荐)

scala> val uniqueTags = scala.collection.mutable.Set[String]()
uniqueTags: scala.collection.mutable.Set[String] = HashSet()

scala> obj.map(_.myList).getOrElse(List.empty[String]).foreach { elem => uniqueTags += elem }

scala> uniqueTags
res13: scala.collection.mutable.Set[String] = HashSet(metal, rock, pop, prog)

答案 1 :(得分:0)

我不确定什么是Obj。但在您这种情况下:obj.flatMap(_.myList)将给出一个Tag列表。我认为正确的方法是:

obj.flatMap(_.myList).foreach(uniqueTags += _)

我认为您可以在Scala中使用可变的。没什么大不了的。根据您的obj,您可以使用其他方式将元素追加到set

case class Obj(myList: List[String])
val obj = Obj(List("1", "2", "3"))

// first example when your obj is a single Obj
val uniqueTags = mutable.Set[String]()
// obj is of type Obj defined in the thrift above
obj.myList.foreach(uniqueTags += _)
printf(uniqueTags.toString()) // give you Set(1, 2, 3)

// second example when your obj is a list of Obj
val obj2 = List(obj, obj, obj)
val uniqueTags2 = mutable.Set[String]()
obj2.flatMap(_.myList).foreach(uniqueTags2 += _)
printf(uniqueTags2.toString()) // give you Set(1, 2, 3) also