zipWithIndex and filter resulting in "Vector" string in output

442 Views Asked by At

I am still struggling a bit with these zipWithIndex and filter functions. I have this code statement , and added a test string to isolate from the rest of the code.

val s = "012345678901234567890123456789012345678901234567890123456789"
val l = s.zipWithIndex.filter{tuple => tuple._2 % 4 == 0}.map{_._1}.toString()

I had expected to get a string with every 5th character from the original string, which does kind-of happen. Instead what I get is:

 Vector(0, 4, 8, 2, 6, 0, 4, 8, 2, 6, 0, 4, 8, 2, 6)

For some reason it seems to have spaces added, and also the word Vector in the string. Where does that come from? It is there without the .toString() (that was to change the type for later). And more to the point, how can I prevent it?

3

There are 3 best solutions below

0
Xavier Guihot On

To join a sequence of characters, you can use mkString:

scala> Vector('1', '2').mkString
res0: String = "12"

in your case:

val l = s.zipWithIndex.filter{tuple => tuple._2 % 4 == 0}.map{_._1}.mkString

Here you're using .toString() which is the usual method used to represent what an object is. In this case a Vector and its content:

scala> Vector('1', '2').toString
res1: String = "Vector(1, 2)"
0
Gabriele Petronella On

You need to explicitly join the members of the vectors, instead of calling toString. You can use mkString for this. Here's a complete working example:

val s = "012345678901234567890123456789012345678901234567890123456789"
val l = s.zipWithIndex.filter{tuple => tuple._2 % 4 == 0}.map{_._1}.mkString
3
prayagupa On

There are already answer above to use mkString("") to concat List data-structures.

you might want to use Range instead of zipWithIndex and make only one traversal on string.

scala> val s = "012345678901234567890123456789012345678901234567890123456789"
s: String = 012345678901234567890123456789012345678901234567890123456789

scala> (0 until s.length by 4).map(index => s(index)).mkString("")
res1: String = 048260482604826

Because underlying java.lang.String maintains an array which means O(1) for retrieval

private final char value[];

public char charAt(int index) {
    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}

it is fp anyway so you might not care about space/time.