Efficient iteration with index in Scala

前端 未结 12 547
后悔当初
后悔当初 2020-12-12 11:57

Since Scala does not have old Java style for loops with index,

// does not work
val xs = Array(\"first\", \"second\", \"third\")
for (i=0; i<         


        
12条回答
  •  离开以前
    2020-12-12 12:18

    The proposed solutions suffer from the fact that they either explicitly iterate over a collection or stuff the collection into a function. It is more natural to stick with the usual idioms of Scala and put the index inside the usual map- or foreach-methods. This can be done using memoizing. The resulting code might look like

    myIterable map (doIndexed(someFunction))
    

    Here is a way to achieve this purpose. Consider the following utility:

    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)
        }
    }
    

    This is already all you need. You can apply this for instance as follows:

    import TraversableUtil._
    List('a','b','c').map(doIndexed((i, char) => char + i))
    

    which results in the list

    List(97, 99, 101)
    

    This way, you can use the usual Traversable-functions at the expense of wrapping your effective function. Enjoy!

提交回复
热议问题