2016-08-11 32 views
0

我的输入文件如下。它包含每个客户的一些购买细节。在scala中我们如何找到每个客户的最新记录?

输入:

100,Surender,2015-01-23,PHONE,20000 
100,Surender,2015-01-24,LAPTOP,25000 
101,Ajay,2015-02-21,LAPTOP,40000 
101,Ajay,2015-03-10,MUSIC_SYSTEM,50000 
102,Vikram,2015-07-20,WATCH,60000 

我的要求是我想找出每个客户的最新购买详情。

因此预期产量

预期输出:

List(101,Ajay,2015-03-10,MUSIC_SYSTEM,50000) 
List(100,Surender,2015-01-24,LAPTOP,25000) 
List(102,Vikram,2015-07-20,WATCH,60000) 

我尝试下面的代码,它是给我预期的输出..

但这以下逻辑有点类似于java。

我的Scala代码:

package pack1 
import scala.io.Source 
import scala.collection.mutable.ListBuffer 
object LatestObj { 

def main(args:Array[String])= 
{ 
    var maxDate ="0001-01-01" 
    var actualData:List[String] =List() 
    var resultData:ListBuffer[String] = ListBuffer() 

    val myList=Source.fromFile("D:\\Scala_inputfiles\\records.txt").getLines().toList; 
    val myGrped = myList.groupBy { x => x.substring(0,3) } 
//println(myGrped) 
    for(mappedIterator <- myGrped) 
     { 
     // println(mappedIterator._2) 
      actualData =mappedIterator._2 
      maxDate=findMaxDate(actualData) 
      println(actualData.filter { x => x.contains(maxDate) }) 
     } 


} 

    def findMaxDate(mytempList:List[String]):String = 
    { 
     var maxDate ="0001-01-01" 
      for(m <- mytempList) 
       { 
       var transDate= m.split(",")(2) 
       if(transDate > maxDate) 
       { 
        maxDate =transDate 
       } 
    } 

    return maxDate 
    } 

    } 

能有人帮我试图用一阶简单的方法相同的方法呢?

或上述代码是实现该逻辑的唯一方法?

+0

“上面的代码是实现该逻辑的唯一方法吗?”不,您正在编写Java-in-Scala。看看集合API(也可能是Scala中的一个教程)。 http://scala-lang.org/api/current/#package虽然你找到了'filter',所以它有点奇怪,你没有注意到'max'和'maxBy' .. –

回答

0

甚至更​​简单的版本,也使用一个案例类与巧合相同的名称。不过,不会删除Tzach之类的不良记录,而是将所有内容都保留为String。

case class Record(id: String, name: String, dateString: String, item: String, count: String) 
    myList.map { line => 
    val Array(id, name, dateString, item, count) = line.split(",") 
    Record(id, name, dateString, item, count) 
    } 
    .groupBy(_.id) 
    .map(_._2.maxBy(_.dateString)) 
    .toList 
+0

你的代码给出了实现这种功能风格逻辑的清晰思路,非常感谢! –

2

下面是使用groupByreduce,再加上使用便捷的情况下,类典雅的代表记录的简单版本:

case class Record(id: Int, username: String, date: Date, product: String, cost: Double) 

val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") 
val stringList = Source.fromFile("./records.txt").getLines().toList 

// split by comma and parse into case class - while REMOVING bad records 
val records = stringList.map(_.split(",")).collect { 
    case Array(id, username, date, product, cost) => Record(id.toInt, username, dateFormat.parse(date), product, cost.toDouble) 
} 

// group by key, and reduce each group to latest record 
val result = records.groupBy(_.id).map { _._2.reduce { 
    (r1: Record, r2: Record) => if (r1.date.after(r2.date)) r1 else r2 
}} 

result.foreach(println) 
// prints: 
// Record(101,Ajay,Tue Mar 10 00:00:00 IST 2015,MUSIC_SYSTEM,50000.0) 
// Record(100,Surender,Sat Jan 24 00:00:00 IST 2015,LAPTOP,25000.0) 
// Record(102,Vikram,Mon Jul 20 00:00:00 IDT 2015,WATCH,60000.0) 

注意,此实现不作任何使用可变变量或收藏,这往往显着简化了代码,并且被认为对于像Scala这样的功能语言更为习惯。

+0

@ Tzach,感谢这个功能逻辑的风格。它帮助我很多 –

相关问题