在scala中为无后减量的序列分配序数
由于我是scala的新手,我在谷歌上搜索了很多东西,在大多数情况下都能找到好的答案。但我找不到这个具体问题的答案,因为谷歌搜索“scala中的后减量”只会让dontcha-use-post-decrement-in-scala-because-its-a-functional-language-answers排名靠前 所以,我真的想知道做以下事情的功能方式是什么:在scala中为无后减量的序列分配序数,scala,Scala,由于我是scala的新手,我在谷歌上搜索了很多东西,在大多数情况下都能找到好的答案。但我找不到这个具体问题的答案,因为谷歌搜索“scala中的后减量”只会让dontcha-use-post-decrement-in-scala-because-its-a-functional-language-answers排名靠前 所以,我真的想知道做以下事情的功能方式是什么: object A { val list = List("a", "b", "c") val map = { var
object A {
val list = List("a", "b", "c")
val map = {
var ord = list.size
Map(list map { x => (x, { val res = ord; ord -= 1; res } ) } : _* )
}
}
class Test extends org.scalatest.FunSuite {
test("") {
println(A.map) // Map(a -> 3, b -> 2, c -> 1)
}
}
它基本上是从给定的列表中创建一个映射,并为列表中的每个元素分配递减的序号(实际代码当然比这个最小的示例更复杂)
我对
var-ord=…
(可变)和{val-res=ord;ord-=1;res}
(减量后)部分特别不满意:/还有其他(更漂亮的)方法吗?你可以简单地写下:
val list = List("a","b","c")
list.map ( elem => (elem, list.size - list.indexOf(elem))).toMap
它将为您提供如下结果:
scala.collection.immutable.Map[String,Int] = Map(a -> 3, b -> 2, c -> 1)
快速解决方案需要颠倒列表,然后您可以使用
zipWithIndex
:
scala> :pa
// Entering paste mode (ctrl-D to finish)
List("a", "b", "c")
.reverse
.zipWithIndex
.toMap
// Exiting paste mode, now interpreting.
res4: scala.collection.immutable.Map[String,Int] = Map(c -> 0, b -> 1, a -> 2)
如果您不介意额外集合的分配,您可以删除视图
这一点很有帮助
list.reverse.zip(1 to list.size + 1).toMap
试试这个:
list.toIterator.zip(Iterator.iterate(list.size){_-1}).toMap
还有另一种变体
list.zip(list.size to 1 by -1).toMap
性能类似于
.reverse.zipWithIndex
,因为reverse
和size
都是O(N)如果两个元素具有相同的值,则会失败。另外,indexOf
是O(N),所以这是毫无意义的慢。虽然公平地说,如果两个元素具有相同的值,OP想要什么还不清楚……我知道,但根据你的问题,我给出了解决方案,但你想多次使用相同的键创建一个映射吗?试试这个(i第二个反转是不必要的,因为映射@TheArchetypalPaul我同意,但我希望示例以OP希望的方式打印出来。也许我应该删除它。@YuvalItzchakov我知道地图没有被排序;)Map的打印顺序只是一个实现工件。我认为,显然说一个人可以可靠地定义order@AlexzipWithIndex
索引从0
开始,您需要手动zip
或添加一个额外的:.map(t=>(t.\u 1,t.\u 2+1)
在zipWithIndex
之后。您不需要+1