val data = List("foo", "bar", "bash")
val selection = List(0, 2)
val selectedData = data.filter(datum => selection.contains(datum.MYINDEX))
// INVALID CODE HERE ^
// selectedData: List("foo", "bash")
假设我想在给定选定索引列表的情况下过滤List
。如果在filter
方法中,我可以引用列表项的索引,那么我可以像上面那样解决这个问题,但datum.MYINDEX
在上述情况下无效。
我怎么能这样做呢?
答案 0 :(得分:7)
如何使用zipWithIndex
来保留对项目索引的引用,如此过滤,然后将索引映射掉?
data.zipWithIndex
.filter{ case (datum, index) => selection.contains(index) }
.map(_._1)
答案 1 :(得分:1)
从另一个角度来做这件事比较简洁(虽然索引可能很慢,因为索引很慢(O(n))。向量会更好。另一方面,contains
的data
中每个项目的另一个解决方案并不是非常快“
val data = List("foo", "bar", "bash")
//> data : List[String] = List(foo, bar, bash)
val selection = List(0, 2)
//> selection : List[Int] = List(0, 2)
selection.map(index=>data(index))
//> res0: List[String] = List(foo, bash)
答案 2 :(得分:0)
我想到的第一个解决方案是创建一个对列表(元素,索引),通过检查选择是否包含该索引来过滤每个元素,然后映射结果列表以便仅保留原始元素(省略索引)。代码是自我解释的:
data.zipWithIndex.filter(pair => selection.contains(pair._2)).map(_._1)
或更具可读性:
val elemsWithIndices = data.zipWithIndex
val filteredPairs = elemsWithIndices.filter(pair => selection.contains(pair._2))
val selectedElements = filteredPairs.map(_._1)
答案 3 :(得分:0)
由于您已经有一个索引列表,最有效的方法是直接选择这些索引:
val data = List("foo", "bar", "bash")
val selection = List(0, 2)
val selectedData = selection.map(index => data(index))
甚至:
val selectedData = selection.map(data)
或者如果您需要保留数据中项目的顺序:
val selectedData = selection.sorted.map(data)
<强>已更新强>
本着寻找所有可能算法的精神,这里使用collect
的版本:
val selectedData = data
.zipWithIndex
.collect {
case (item, index) if selection.contains(index) => item
}
答案 4 :(得分:0)
本作品:
val data = List("foo", "bar", "bash")
val selection = List(0, 2)
val selectedData = data.filter(datum => selection.contains(data.indexOf(datum)))
println (selectedData)
输出: 列表(foo,bash)
答案 5 :(得分:0)
以下是在效率方面可能最具扩展性的方式,与SO上的许多答案不同,它实际上完全遵循官方的scala风格指南。
import scala.collection.immutable.HashSet
val selectionSet = new HashSet() ++ selection
data.zipWithIndex.collect {
case (datum, index) if selectionSet.contains(index) => datum
}
如果要将结果集合传递给其他map
,flatMap
等,建议将data
转换为延迟序列。实际上也许你应该这样做,以避免2遍,zipWithIndex
collect
一个,但我怀疑基准时会有多少收获。
答案 6 :(得分:0)
实际上有一种更简单的方法可以使用map
方法按索引进行过滤。这是一个例子
val indices = List(0, 2)
val data = List("a", "b", "c")
println(indices.map(data)) // will print List("a", "c")