如何获取SortedSet中项的索引

时间:2016-02-05 11:11:18

标签: scala sortedset

我正在实现某种“记录矩阵”,其中轴索引是某种类型K(例如字符串)的(唯一)键。这些键不需要排序,但我需要一个订单,所以我去了一个SortedSet。

键的主要用途(SortedSet)是在底层的二维数据数组中找到实际的整数索引(Seq[Seq[.]]或者是什么)。 但是我无法找到获得这种f(key: K): Int功能的方法。

而不是SortedSet[K],我可以使用Map[K,Int]哪些值是索引,但我发现它有点过分(并且没有很好地输入)。

有什么想法吗?

修改

Map方法类似,但在2D中:

val myKeys = // SortedSet("A", "B", "C")
val data   = // Array(13,42,117)
val keyIndices = myKeys.zipWithIndex.toMap

// get indices of "B", and lookup in data array
data(keyIndices("B"))

我为Map解决方案编写了“not well typed”,因为类型不保证索引是连续的并且从0开始。而在有序seq中的位置是。

所选解决方案

我选择了Neumann's answer,因为它最适合我的实际问题。但Cipcigan'sVerkerk's的答案更符合标题。

3 个答案:

答案 0 :(得分:1)

使用zipWithIndex应该这样做:

def getIndex[T](xs: scala.collection.SortedSet[T], x:T): Option[Int] =
   xs.zipWithIndex.find(_._1 == x).map(_._2)

val a = scala.collection.SortedSet("a", "l", "m", "o", "n", "d")

getIndex(a, "a") // => Some(0)
getIndex(a, "m") // => Some(3)
getIndex(a, "x") // => None

答案 1 :(得分:1)

您可以创建一个隐式类来将功能添加到SortedSet

implicit class SortedListFunctions[T](val s: SortedSet[T]){
    def getIndex(key: T): Int = {
        val notDropped = s.dropWhile(_ != key).size

        if(notDropped == 0) -1
        else s.size - notDropped
    }
}

使用隐式类,如果它存在于API

中,则可以调用getIndex(..)a
 set.getIndex(key)

请注意,这可能不是搜索已排序内容的非常有效的方法。 如果您的SortedSet非常大,您可能会考虑Binary Searching

答案 2 :(得分:1)

简短回答

保持Set你不能。有办法通过索引获取元素是Seq的特征。

scala> val data =scala.collection.SortedSet("a", "l", "m", "o", "n", "d")
data: scala.collection.SortedSet[String] = TreeSet(a, d, l, m, n, o)

scala> data(1)
<console>:12: error: type mismatch;
found   : Int(1)
required: String
   data(1)
        ^

scala> data("a")
res3: Boolean = true

我在这个例子中显示了apply方法检查给定的参数是否包含在集合中。

我会使用您已使用Map建议的方法。或者将数据转换为Seq

scala> val indexedData = data.toVector
indexedData: Vector[String] = Vector(a, d, l, m, n, o)

scala> indexedData(2)
res9: String = l

scala> indexedData.indexOf("l")
res1: Int = 2