Coolsam
Coolsam

Reputation: 31

How to write single line scala codes?

I'm new to Scala and I've written a piece of code that takes employee file(empId, name, age, salary, department) as an input and prints out the department and the total salary in the department.

It is a novice code. How to I shorten the code? Please help

Code:

object UsingCollectionMaps {
  def main(a: Array[String]) {
    val filename = "Employee.txt"
    var map = collection.mutable.Map[String,Long]()
    var sal: Long = 0
    for (line <- Source.fromFile(filename).getLines()) {
      val fields = line.split(",")
      if (map.contains(fields(4))) {
        map.put(fields(4), (map(fields(4)) + fields(3).toLong))
      } else {
        map.put(fields(4), fields(3).toLong)
      }
    }
    println(map)
  }
}

Upvotes: 1

Views: 494

Answers (3)

Noam
Noam

Reputation: 1022

I would try to avoid those mutable structures and also to make sense of this file, properly part it to a case class. After that, the use of groupBy and sum.

import scala.io.Source

case class Employee(empId: String, name: String, age: Int,
                    salary: Long, department: Int)

Source.fromFile("someFile.txt")
      .getLines()
      .map( _.split(",") )
      .map( l => Employee(l(0), l(1), l(2).toInt,
                          l(3).toLong, l(4).toInt) )
      .toSeq
      .groupBy( _.department )
      .mapValues( _.map( _.salary ).sum )

Upvotes: 8

Marth
Marth

Reputation: 24812

You could use the .groupBy method to create a Map of 'Departement' -> 'Employees' and then sum their salaries:

object UsingCollectionMaps {
  def main(a:Array[String]){
    val filename = "Employee.txt"
    val lines = io.Source.fromFile(filename).getLines().toList
    val map = employees.map(_.split(","))
                       .groupBy(_(4))  // Group by the fourth element of the arrays
                       .mapValues(_.map(_(3).toLong).sum) // Map an employeeList to their salaries and sum them
    println(map)
  }
}

Upvotes: 4

Chris Martin
Chris Martin

Reputation: 30736

This isn't considerably shorter, but does take a more functional approach:

import collection.immutable.Map
import io.Source

object UsingCollectionMaps {
  def main(args: Array[String]) {
    println(
      Source.fromFile("Employee.txt").getLines()
        .foldLeft(Map.empty[String, Long])({
          case (totals, line) =>
            val fields = line.split(",")
            val department = fields(4)
            val salary = fields(3).toLong
            totals.updated(department, 
              totals.getOrElse(department, 0L) + salary)
        })
    )
  }
}

Upvotes: 3

Related Questions