In this code I want to increment index
to put it to each yield
ing result.
var index=0
for(str <- splitToStrings(text) ) yield {
if (index != 0) index += 1 // but index is equal to `0` all the time
new Word(str, UNKNOWN_FORM, index )
}
Why I can not change index
? And what the best way to implement this logic then, trying to be concise?
The zipWithIndex
method on most sequence-like collections will give you a zero-based index, incrementing with each element:
for ((str, index) <- splitToStrings(text).zipWithIndex)
yield new Word(str, UNKNOWN_FORM, index)
Because initially index is set to 0, thus your condition index != 0
is never executes to true and index is never got incremented. Maybe you don't need this condition? Maybe you can count results afterwards? Now I see that index is used within loop. Then you have to either use @BenJames answer or go recursive.
zipWithIndex
will copy and create a new collection, so better make it lazy when the collection is potentially large
for ((str, index) <- splitToStrings(text).view.zipWithIndex)
yield new Word(str, UNKNOWN_FORM, index)
In fact, if you are working with an indexed sequence, then a more efficient way is to use indices
, which produces the range of all indices of this sequence.
val strs = splitToStrings(text)
for(i <- strs.indices) yield {
new Word(strs(i), UNKNOWN_FORM, i )
}
splitToStrings(text).foldLeft(0,List[Word]){(a,b) => {
if(a._1!=0) (a._1+1,new Word(str, UNKNOWN_FORM, index) :: b)
else (a._1,new Word(str, UNKNOWN_FORM, index) :: b)
}}
I am using foldLeft
here with a tuple as: starting base with index = 0
and an empty List
. I then iterate over each element.
Above a
is this tuple. I check the index
value and increment it. Else I dont add the index
. And I add the new Word
to the list.
Ultimately in the end you get a tuple containing the index value and the total List containing all Words.