在Scala中,我有时使用Map [A,Boolean],有时使用Set [A]。这两个概念之间真的没什么区别,实现可能会使用相同的数据结构来实现它们。那么为什么还要烦恼呢?正如我所说,这个问题与Scala有关,但它会出现在任何编程语言中,它的库实现了Set抽象。
答案 0 :(得分:2)
在Set上定义了一些特定的方便方法(intersect,diff等)。没什么大不了的,但往往很有用。
答案 1 :(得分:2)
我的第一个想法是两个:
此外,应用程序的语义也发生了变化:
val map: Map[String, Bool] = Map("hello" -> true, "world" -> false)
val set: Set[String] = Set("hello")
map("hello") // true
map("world") // false
map("none!") // EXCEPTION
set("hello") // true
set("world") // false
set("none!") // false
无需实际存储额外的对来指示缺席(更不用说实际上表明缺席的布尔值)。
设置是非常好的,表明存在某些东西,这使它们非常适合过滤:
val map = (0 until 10).map(_.toString).zipWithIndex.toMap
val set = (3 to 5).map(_.toString).toSet
map.filterKeys(set) // keeps pairs 3rd through 5th
就处理集合而言,地图很适合表示关系,这使得它们非常适合收集:
set.collect(map) // more or less equivalent as above, but only values are returned
您可以阅读有关使用集合作为处理其他集合here的函数的更多信息。
答案 2 :(得分:1)
有几个原因:
1)更容易思考/使用只有单个元素的数据结构,而不是映射到虚拟true
,
例如,将列表转换为Set
,然后转换为Map
更容易:
scala> val myList = List(1,2,3,2,1)
myList: List[Int] = List(1, 2, 3, 2, 1)
scala> myList.toSet
res9: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> myList.map(x => (x, true)).toMap
res1: scala.collection.immutable.Map[Int,Boolean] = Map(1 -> true, 2 -> true, 3 -> true)
2)正如Kombajnzbożowy所指出的,集合还有其他辅助方法,union
,intersect
,diff
,subsetOf
。
3)Sense Set
没有映射到虚拟变量,内存中的一个集合的大小更小,这对于小型密钥更明显。
如上所述,并非所有语言都有Set
数据结构,例如Go
没有。