Scala:获取地图中元素的索引
Scala: Getting the index of an element in a Map
我有一个 Map[String, Object]
,其中的键是一个 ID。该 ID 现在在另一个对象中引用,我必须知道该 ID 具有的索引(地图中的位置)。我不敢相信没有 .indexOf
我怎样才能做到这一点?
我真的必须为自己构建一个包含所有键的列表或另一个具有 ID1 -> 1、ID2 -> 2 的 Map 吗?
我必须多次获取 ID 的索引。 List
或那个 Map 会更有效率吗?
根据定义,地图没有索引。
您可以枚举映射中的键,但这不能保证stable/repeatable。添加一个新元素,它可能会由于重新散列而随机更改每个其他元素的编号。如果你想要一个键到索引的稳定映射(或相反),你必须将这个映射存储在某个地方,例如通过将地图序列化为列表。
将 Map[A,B]
转换为有序集合,例如 Seq[(A,B)]
配备 indexOf
方法。注意
val m = Map("a" -> "x", "b" -> "y")
那个
m.toSeq
Seq[(String, String)] = ArrayBuffer((a,x), (b,y))
从上面的广泛讨论中可以看出,此转换不保证生成的有序集合中的任何特定顺序。这个集合可以根据需要进行排序。
或者,您可以索引映射中的键集,例如,
val idxm = for ( ((k,v),i) <- m.zipWithIndex ) yield ((k,i),v)
Map[(String, Int),String] = Map((a,0) -> x, (b,1) -> y)
其中等价于 indexOf
的地方例如
idxm.find { case ((_,i),v) => i == 1 }
Option[((String, Int), String)] = Some(((b,1),y))
@Dora,正如大家提到的那样,地图是无序的,因此无法就地索引它们并将 id 与它们一起存储。
很难猜测在地图中存储 (K,V) 对然后为每个 K 获取唯一 ID 的用例。因此,根据我的理解,这些是一些建议 -
1. 您可以使用 LinkedHashMap 而不是 Map ,这将保持插入顺序,因此您将获得稳定的迭代。在此地图上获取 KeysIterator 并将其转换为一个列表,该列表为您提供地图中每个键的唯一索引。像这样-
import scala.collection.mutable.LinkedHashMap
val myMap = LinkedHashMap("a"->11, "b"->22, "c"->33)
val l = myMap.keysIterator.toList
l.indexOf("a") //get index of key a
myMap.+=("d"->44) //insert new element
val l = myMap.keysIterator.toList
l.indexOf("a") //index of a still remains 0 due to linkedHashMap
l.indexOf("d") //get index of newly inserted element.
很明显,与HashMaps相比,在linkedHashMap中插入元素是昂贵的。
从 Map 中删除元素会自动将索引向左移动。
myMap.-=("b")
val l = myMap.keysIterator.toList
l.indexOf("c") // Index of "c" moves from 2 to 1.
将 (K->V) 映射到 (K->(index, v)) 并在插入新元素时手动生成索引。
class ValueObject(val index: Int, val value: Int)
val myMap = scala.collection.mutable.Map[String, ValueObject]()
myMap.+=("a"-> new ValueObject(myMap.size+1, 11))
myMap("a").index<br/> // get index of key a
myMap.+=("b"-> new ValueObject(myMap.size+1, 22))
myMap.+=("c"-> new ValueObject(myMap.size+1, 33))
myMap("c").index<br/> // get index of key c
myMap("b").index<br/> // get index of key b
如果我们需要没有间隙的索引,删除会很昂贵,因为我们需要相应地更新所有键。但是,键插入和搜索会更快。
如果我们确切地知道您需要什么,这个问题就可以得到有效解决,所以如果上述解决方案不适合您,请解释!!! (也许你真的不需要地图来解决你的问题)
我有一个 Map[String, Object]
,其中的键是一个 ID。该 ID 现在在另一个对象中引用,我必须知道该 ID 具有的索引(地图中的位置)。我不敢相信没有 .indexOf
我怎样才能做到这一点?
我真的必须为自己构建一个包含所有键的列表或另一个具有 ID1 -> 1、ID2 -> 2 的 Map 吗?
我必须多次获取 ID 的索引。 List
或那个 Map 会更有效率吗?
根据定义,地图没有索引。
您可以枚举映射中的键,但这不能保证stable/repeatable。添加一个新元素,它可能会由于重新散列而随机更改每个其他元素的编号。如果你想要一个键到索引的稳定映射(或相反),你必须将这个映射存储在某个地方,例如通过将地图序列化为列表。
将 Map[A,B]
转换为有序集合,例如 Seq[(A,B)]
配备 indexOf
方法。注意
val m = Map("a" -> "x", "b" -> "y")
那个
m.toSeq
Seq[(String, String)] = ArrayBuffer((a,x), (b,y))
从上面的广泛讨论中可以看出,此转换不保证生成的有序集合中的任何特定顺序。这个集合可以根据需要进行排序。
或者,您可以索引映射中的键集,例如,
val idxm = for ( ((k,v),i) <- m.zipWithIndex ) yield ((k,i),v)
Map[(String, Int),String] = Map((a,0) -> x, (b,1) -> y)
其中等价于 indexOf
的地方例如
idxm.find { case ((_,i),v) => i == 1 }
Option[((String, Int), String)] = Some(((b,1),y))
@Dora,正如大家提到的那样,地图是无序的,因此无法就地索引它们并将 id 与它们一起存储。
很难猜测在地图中存储 (K,V) 对然后为每个 K 获取唯一 ID 的用例。因此,根据我的理解,这些是一些建议 -
1. 您可以使用 LinkedHashMap 而不是 Map ,这将保持插入顺序,因此您将获得稳定的迭代。在此地图上获取 KeysIterator 并将其转换为一个列表,该列表为您提供地图中每个键的唯一索引。像这样-
import scala.collection.mutable.LinkedHashMap
val myMap = LinkedHashMap("a"->11, "b"->22, "c"->33)
val l = myMap.keysIterator.toList
l.indexOf("a") //get index of key a
myMap.+=("d"->44) //insert new element
val l = myMap.keysIterator.toList
l.indexOf("a") //index of a still remains 0 due to linkedHashMap
l.indexOf("d") //get index of newly inserted element.
很明显,与HashMaps相比,在linkedHashMap中插入元素是昂贵的。
从 Map 中删除元素会自动将索引向左移动。
myMap.-=("b")
val l = myMap.keysIterator.toList
l.indexOf("c") // Index of "c" moves from 2 to 1.
将 (K->V) 映射到 (K->(index, v)) 并在插入新元素时手动生成索引。
class ValueObject(val index: Int, val value: Int) val myMap = scala.collection.mutable.Map[String, ValueObject]() myMap.+=("a"-> new ValueObject(myMap.size+1, 11)) myMap("a").index<br/> // get index of key a myMap.+=("b"-> new ValueObject(myMap.size+1, 22)) myMap.+=("c"-> new ValueObject(myMap.size+1, 33)) myMap("c").index<br/> // get index of key c myMap("b").index<br/> // get index of key b
如果我们需要没有间隙的索引,删除会很昂贵,因为我们需要相应地更新所有键。但是,键插入和搜索会更快。
如果我们确切地知道您需要什么,这个问题就可以得到有效解决,所以如果上述解决方案不适合您,请解释!!! (也许你真的不需要地图来解决你的问题)