我怎样才能使用地图,并在斯卡拉接收索引?
是否有任何内置的列表/序列的行为像map
并提供元素的索引?
我相信你正在寻找zipWithIndex?
scala> val ls = List("Mary", "had", "a", "little", "lamb") scala> ls.zipWithIndex.foreach{ case (e, i) => println(i+" "+e) } 0 Mary 1 had 2 a 3 little 4 lamb
来自: http : //www.artima.com/forums/flat.jsp?forum= 283& thread=243570
你也有像这样的变化:
for((e,i) <- List("Mary", "had", "a", "little", "lamb").zipWithIndex) println(i+" "+e)
要么:
List("Mary", "had", "a", "little", "lamb").zipWithIndex.foreach( (t) => println(t._2+" "+t._1) )
使用 。 地图 。 zipWithIndex
val myList = List("a", "b", "c") myList.zipWithIndex.map { case (element, index) => println(element, index) s"${element}(${index})" }
结果:
List("a(0)", "b(1)", "c(2)")
所提出的解决scheme受到这样的事实的影响,即它们创build中间集合或者引入并非严格必要的variables。 最终你需要做的就是跟踪迭代步骤的数量。 这可以通过记忆来完成。 生成的代码可能看起来像
myIterable map (doIndexed(someFunction))
doIndexed
函数包装内部函数,该函数接收索引和myIterable
的元素。 您可能从JavaScript中熟悉这一点。
这是达到这个目的的一种方法。 考虑下面的工具:
object TraversableUtil { class IndexMemoizingFunction[A, B](f: (Int, A) => B) extends Function1[A, B] { private var index = 0 override def apply(a: A): B = { val ret = f(index, a) index += 1 ret } } def doIndexed[A, B](f: (Int, A) => B): A => B = { new IndexMemoizingFunction(f) } }
这已经是你所需要的了。 你可以应用这个例子如下:
import TraversableUtil._ List('a','b','c').map(doIndexed((i, char) => char + i))
结果在列表中
List(97, 99, 101)
这样,你可以使用通常的Traversable函数来代替包装你的有效函数。 开销是在其中创build记忆对象和计数器。 否则这个解决scheme在内存或性能方面与使用非索引map
一样好(或不好)。 请享用!
在CountedIterator
中有CountedIterator(你可以从普通的迭代器中获得.counted)。 我相信它已经被弃用(或者简单地被删除)在2.8,但它很容易推出自己的。 你需要能够命名迭代器:
val ci = List("These","are","words").elements.counted scala> ci map (i => i+"=#"+ci.count) toList res0: List[java.lang.String] = List(These=#0,are=#1,words=#2)
或者,假设你的集合有不断的访问时间,你可以映射索引列表,而不是实际的集合:
val ls = List("a","b","c") 0.until(ls.length).map( i => doStuffWithElem(i,ls(i)) )