通过一组键过滤和排序Map的最佳方法

时间:2015-10-04 16:50:33

标签: scala

我有一个Map实例(不可变):

val source = Map(
    ("foo", "spam"),
    ("bar", "hoge"),
    ("baz", "eggs"),
    ("qux", "corge"),
    ("quux", "grault")
  )

我在源地图中可能存在或不存在某些顺序的键(Set或List):

baz
foo
quuuuux // does not exist in a source map

但是,使用简洁的scala样式迭代源地图的最佳和最干净的方法是什么,通过我的键过滤它并将过滤后的项目按照与键相同的顺序放入结果地图中?

Map(baz -> eggs, foo -> spam)

P.S。为了澄清 - 结果映射中键的顺序必须与过滤键列表中的键相同

3 个答案:

答案 0 :(得分:3)

val keys = List("foo", "bar")
val map = Map("foo" -> "spam", "bar" -> "hoge", "baz" -> "eggs")

keys.foldLeft(ListMap.empty[String, String]){ (acc, k) => 
  map.get(k) match {
    case Some(v) => acc + (k -> v)
    case None => acc
  }
}

这将遍历键,构建仅包含匹配键的映射。

请注意,您需要ListMap来保留密钥的顺序,尽管ListMap的实现将按照它们插入的相反顺序返回元素(因为密钥被添加为列表)

LinkedHashMap可以确保精确的广告订单顺序,但它是一个可变的数据结构。

答案 1 :(得分:3)

如果您需要订购/usr/local/Cellar/sdl_mixer/1.2.12/include/SDL/SDL_mixer.h /usr/local/Cellar/sdl_mixer/1.2.12/lib/libSDL_mixer-1.2.0.dylib /usr/local/Cellar/sdl_mixer/1.2.12/lib/pkgconfig/SDL_mixer.pc /usr/local/Cellar/sdl_mixer/1.2.12/lib/ (2 other files) ,则可以使用Map之类的内容来定制自定义键。所以给出了

TreeMap

您可以选择,迭代订购的密钥:

import scala.collection.immutable.TreeMap

val source = Map(
  ("foo", "spam"),
  ("bar", "hoge"),
  ("baz", "eggs"),
  ("qux", "corge"),
  ("quux", "grault")
)
val order: IndexedSeq[String] = IndexedSeq("baz", "foo", "quuuuux")
implicit val keyOrdering: Ordering[String] = Ordering.by(order.indexOf)

或从源地图过滤:

val result1: TreeMap[String, String] = order.collect {
  case key if source.contains(key) => key -> source(key)
}(collection.breakOut)

// or a bit shorter
val result2: TreeMap[String, String] = order.flatMap { key => source.get(key).map(key -> _) }(collection.breakOut)

我不确定哪一个最有效,但我怀疑val result3: TreeMap[String, String] = TreeMap.empty ++ source.filterKeys(order.contains) 可能是最快的,至少对你的简单例子而言。虽然,imho,最后一个例子比其他例子更易读。

答案 2 :(得分:3)

如果你有:

val source = Map(
  "foo" -> "spam",
  "bar" -> "hoge",
  "baz" -> "eggs",
  "qux" -> "corge",
  "quux" -> "grault"
 )

val keys = List( "baz", "foo", "quuuux" )

然后,你可以:

import scala.collection.immutable.SortedMap

SortedMap(source.toSeq:_*).filter{ case (k,v) => keys.contains(k) }