1

I'm reading a text file and have the syntax set up correctly to do so. What I want to do now is append all the integers into an array, but when I try to use a print statement to check what's going on, nothing shows up in the terminal.

package lecture

import scala.io.{BufferedSource, Source}

object LectureQuestion {
  def fileSum(fileName: String): Int = {
    var arrayOfnumbers = Array[String]()
    var fileOfnumbers: BufferedSource = Source.fromFile(fileName)
    for (line <- fileOfnumbers.getLines()){
      val splits: Array[String] =line.split("#")
      for (number <- splits){
        arrayOfnumbers :+  number
        println(arrayOfnumbers.mkString(""))
      }
      //println(splits.mkString(" "))
    }

3

  }

  def main(args: Array[String]): Unit = {
    println(fileSum("data/fileOfnumbers.txt"))
  }
}

I set up a blank array to append the numbers to. I tried switching var to val, but that wouldn't make sense as var is mutuable, meaning it can change. I'm pretty sure the way to add things to an array in Scala is :+, so I'm not sure what's going on.

jwvh
  • 50,871
  • 7
  • 38
  • 64
indentation
  • 77
  • 2
  • 9
  • 2
    `:+` creates a new **Array** instead of mutating that one. You can `arrayOfNumbers = arrayOfNumbers :+ number`. However, appending just one element in an **Array** is very inefficient. I would suggest using other data structures like an **ArrayBuilder** or a **ListBuilder** or even rethinking your logic so you do not need any kind of mutability. – Luis Miguel Mejía Suárez Jan 03 '20 at 04:35
  • My bad, I didn't even know an arrayBuilder/listBuilder existed. – indentation Jan 03 '20 at 04:54
  • 3
    You don't get much help from the compiler, or the scaladoc, which is too bad. It doesn't tell you that you are discarding a useful result. It doesn't tell you that appending to an array is bad. The 2.13 scaladoc does say "alias for appended", where the "ed" suffix means a copy was made. That doesn't rise to the bar of great ergonomics. There is a sense in which "array" is a fundamental concept, and we know an array doesn't have a position pointer for mutable appends. But I don't think that lets the tooling off the hook. – som-snytt Jan 03 '20 at 06:33
  • 2
    Why are you trying to build an `arrayOfnumbers` when `splits` is **already** an `Array` of the digits between the `#` delimiters? It makes no sense. – jwvh Jan 03 '20 at 06:39
  • 3
    @identation given you are just learning and you will have a lot of _"simple & small"_ questions. I would recommend you to ask them in the [**gitter** channel](https://gitter.im/scala/scala). That is a better place for this kind of questions and you will get answers more quickly, and since it is a chat it will be more interactive. – Luis Miguel Mejía Suárez Jan 03 '20 at 12:29

1 Answers1

0

In Scala all you would need is flatMap the List of a List and then sum the result.

Here your example simplified, as we have extracted the lines already:

import scala.util.Try

  def listSum(lines: List[String]): Int = {    
    (for{
      line <- lines
      number <- line.split("#").map(n => Try(n.trim.toInt).getOrElse(0))
    } yield number).sum
  }

  listSum(List("12#43#134#bad","13#54#47")) // -> 303

No vars, resp. no mutability needed. Just a nice for-comprehension;).

And for comparison the solution with flatMap:

  def listSum(lines: List[String]): Int = {
    lines
      .flatMap(_.split("#").map(n => Try(n.trim.toInt).getOrElse(0)))
      .sum
  }
pme
  • 14,156
  • 3
  • 52
  • 95
  • What if it's a really big list? It might fit in memory, but what if other things also want to fit in memory? – som-snytt Jan 03 '20 at 07:23
  • 1
    @som-snytt then it would need a different solution. Check for example here: https://stackoverflow.com/a/24485334/2750966 – pme Jan 03 '20 at 07:28
  • 2
    Or we may take advantage that the values come from a file and the `getLines` method on **Source** returns an **Iterator**. Also [I already](https://stackoverflow.com/questions/59570693/string-splitting-splitting-by-hashtag#comment105309253_59570693) showed the entire solution to OP, but it seems he / she just wants the concrete answer to each specific problem, so he/she can come up with the solution by him/her self. Which I agree in that being a reasonable idea given he/she is just learning. – Luis Miguel Mejía Suárez Jan 03 '20 at 12:27