3

I am trying to append to an array but for some reason it is just appending blanks into my Array.

  def schemaClean(x: Array[String]): Array[String] =
  {
    val array = Array[String]()
    for(i <- 0 until x.length){
      val convert = x(i).toString
      val split = convert.split('|')
      if (split.length == 5) {
        val drop = split.dropRight(3).mkString(" ")
        array :+ drop
      }
      else if (split.length == 4) {
        val drop = split.dropRight(2).mkString(" ")
        println(drop)
        array :+ drop.toString
        println(array.mkString(" "))
      }
    }
   array
  }


  val schema1 = schemaClean(schema)

prints this:

record_id string

assigned_offer_id string

accepted_offer_flag string

current_offer_flag string

If I try and print schema1 its just 1 blank line.

1
  • 2
    You are not storing the new array's reference anywhere. (array :+ drop, array :+ drop.toString) array should be a var imho (or use fold/...). Commented May 29, 2015 at 19:02

1 Answer 1

7

Scala's Array size is immutable. From Scala's reference:

def
    :+(elem: A): Array[A] 

[use case] A copy of this array with an element appended.

Thus :+ returns a new array whose reference you are not using.

val array = ...

Should be:

var array = ...

And you should update that reference with the new arrays obtained after each append operation.

Since there are not variable size arrays in Scala, the alternative to an Array var copied after insertion is BufferArray, use its method operator += to append new elements and obtain the resulting array from the buffer, e.g:

import scala.collection.mutable.ArrayBuffer
val ab = ArrayBuffer[String]()
ab += "hello"
ab += "world"
ab.toArray

res2: Array[String] = Array(hello, world)

Applied to your code:

def schemaClean(x: Array[String]): Array[String] =
  {
    val arrayBuf = ArrayBuffer[String]()
    for(i <- 0 until x.length){
      val convert = x(i).toString
      val split = convert.split('|')
      if (split.length == 5) {
        val drop = split.dropRight(3).mkString(" ")
        arrayBuf += drop
      }
      else if (split.length == 4) {
        val drop = split.dropRight(2).mkString(" ")
        println(drop)
        arrayBuf += drop.toString
        println(arrayBuf.toArray.mkString(" "))
      }
    }
   arrayBuf.toArray
  }
Sign up to request clarification or add additional context in comments.

3 Comments

Wonderful thank you for not only giving the answer but also explaining why! New to this language and its subtle nuances!
A bit of a correction: Scala arrays are NOT immutable. As in Java, the length of a Scala array cannot be modified, so :+ necessarily creates a copy. But arrays can be updated in-place with statements like myArray(0) = newVal;. You'll get yourself into all kinds of trouble if you treat arrays as immutable and therefore thread-safe.
@SteveWaldman Thanks for the observation, I've edited my answer to include the correction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.