【问题标题】:Elegant map implementation优雅的地图实现
【发布时间】:2011-09-08 19:33:34
【问题描述】:

有一个有序字符串列表要与另一个列表进行比较,我决定将其实现为一个映射,其中键是字符串的第一个字符,值是具有相同第一个字符的字符串列表。 简而言之,我有这样的东西:

var list1:Map[Char, List[String]] = Map('a' -> List("alone", "away"))
var list2:List[String] = List("I", "am", "alone", "at", "home", "watching", "batman", "XD")

现在,以这种方式实现了我的代码,很难与他们一起尝试将第一个列表视为一个简单的列表,所以我想知道是否有另一种更优雅的方法来解决这个问题。 如果我必须验证 list1 是否有“单独”,我必须首先获取密钥“a”,然后调用方法包含。我必须实现这样的事情。

if ( list1( "alone".charAt(0) ).contains( "alone" ) ) ...

每次都必须提取密钥然后比较列表是很难看的,我想创建一个新的地图(或列表)来实现这一点(它会自动提取密钥然后在列表)。 你有什么建议? 谢谢。

编辑:我重写了部分问题,澄清了一些观点。 第一个列表是有序的,第二个没有。

【问题讨论】:

  • 你有有序字符串列表吗?还是一个有序的字符串列表?为什么你有这张奇怪的地图?为什么不使用简单的列表?
  • 好吧,我有一个有序字符串的列表,我以这种方式实现了我的代码,相信它可以更快地进行搜索和替换以及其他一些事情。我的意思是,在较小的列表中搜索比在所有列表中搜索更快,不是吗?
  • 您最好使用Vector。这样的操作相当有效。
  • Vector有什么优势?没有关于 scala-lang 文档的描述。
  • 我不熟悉 scala,但你能不能只使用集合及其操作? - 无论如何..在这种情况下排序列表,为什么不迭代一个列表,将每个元素与另一个列表中相同位置的元素进行比较? O(n)

标签: list scala collections map set


【解决方案1】:

从我所看到的所有情况来看,你真的只想要一个列表。所以使用列表。 (或者可能是一个 SortedSet http://www.scala-lang.org/api/current/scala/collection/SortedSet.html

您似乎关心性能,但您既没有说明哪个算法的哪一部分要慢,也没有说明它需要多快,也没有提供合理的论据证明您选择的方法确实满足这些性能要求。再说一遍:只需使用 List。然后测量性能。如果它真的很慢,请在此处发布代码和结果创建一个基准,并说明它需要多快。

然后人们将能够提供帮助。

【讨论】:

  • 我同意,我没有注意到还有一个 HashSet... 你知道,当你来自脚本语言 (autoit) 时,你不能期望什么都知道。感谢您的建议。再见。
【解决方案2】:

我不确定为什么使用地图可以帮助您比较字符串列表,但无论如何:

如果您不介意使用可变集合,并且您确定列表中没有重复(因此您实际上可以使用集合),那么您可以使用 MultiMap 特征:

import scala.collection.mutable._
val mm = new HashMap[Char,Set[String]] with MultiMap[Char,String]
Seq("alone","away").foreach(s => mm.addBinding(s(0),s))

scala> mm
res2: scala.collection.mutable.HashMap[Char,scala.collection.mutable.Set[String]]
 with scala.collection.mutable.MultiMap[Char,String] = 
 Map(a -> Set(alone, away))

scala> mm.entryExists('a',"alone")

不幸的是,当您使用集合操作时,多重映射就会消失(它只是从CharSet[String] 的普通映射)。

【讨论】:

  • 我想解决 ('a',"alone") 部分...我想像 mm.contains("alone") 那样做一些事情,它会自动像 mm("单独".charAt(0) ).contains("单独")...
  • @DDB - 如果您实际上从不需要'a' 本身,我认为这清楚地表明您没有采取正确的方法来解决您的问题。另外,不要忘记您可以只使用def has(m: Map[Char,List[String]], s: String) = if (s.length>0) m.get(s.charAt(0)).map(_ contains s).getOrElse(false) else false,然后使用它而不是每次都输入整个混乱。
  • 也许我可以使用隐式定义来解决问题...我没有这样想...
  • @DDB - 如果您希望语法 m 具有“apples”而不是 has(m,"apples"),则可以使用隐式转换。否则,后者效率更高。
猜你喜欢
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-10
  • 2011-01-16
  • 1970-01-01
  • 2015-09-25
相关资源
最近更新 更多