use*_*418 3 scala scala-collections
比方说,我有一个清单.如果我想在该列表的索引处返回一些内容,我可以传递列表'val,索引.像这样.
val list = List(1, 2, 3)
list(0) //Int = 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我想在此列表中的多个索引处的项目怎么办?我希望能够做到这一点...... list(0, 1)并获得这些指数的项目集合.
这在Ruby中非常简单.有人有什么建议吗?
Ben*_*ich 10
您可以翻转逻辑,这样对于每个索引,您获得索引,就可以在该索引处检索元素.由于您正在使用该apply方法List,因此该逻辑有几个简写表达式:
val indices = List(0, 1)
indices.map(index => list.apply(index))
indices.map(index => list(index))
indices.map(list(_))
indices.map(list)
indices map list
Run Code Online (Sandbox Code Playgroud)
值得注意的是,由于这些都是maps开启的indices,因此产生的集合通常具有相同的类型indices,而不是list:
val list = Array(1, 2, 3)
val indices = List(0, 1)
indices map list //List(1, 2), instead of Array(1, 2)
Run Code Online (Sandbox Code Playgroud)
这可能是一个不受欢迎的财产.一个解决方案是使用breakOut(in scala.collection):
val newList: Array[Int] = indices.map(list)(breakOut)
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读有关breakOut的更多信息.以下解决方案还list通过执行操作list来维护集合类型,而不是indeces:
如果您要查找列表的连续范围,可以考虑使用slice:
list.slice(1, 2) //List(2)
Run Code Online (Sandbox Code Playgroud)
您也可以使用drop和take(与dropRight,takeRight版本)到类似的效果:
list.drop(1).take(1)
Run Code Online (Sandbox Code Playgroud)
对于此类过滤的更复杂版本,您可能对该zipWithIndex方法感兴趣,该方法允许您在索引上表达任意逻辑:
list.zipWithIndex.collect {
case(el, index) if indices.contains(index) /* any other logic */ => el
}
Run Code Online (Sandbox Code Playgroud)
@Ben 的回答很准确。
但是,如果您希望能够使用您所描述的语法list(0, 1),那么 Scala 允许您通过隐式转换来实现这一点:
implicit class MultiIndexList[A](list: List[A]){
def apply(indices: Int *) = indices.map(list)
}
Run Code Online (Sandbox Code Playgroud)
假设您正在开发 REPL:
val list = List(1,2,3)
list(1,2)
res1: Seq[Int] = ArrayBuffer(2, 3)
list(0,2)
res2: Seq[Int] = ArrayBuffer(1, 3)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3347 次 |
| 最近记录: |