2016-08-11 33 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,感謝這個功能邏輯的風格。它幫助我很多 –

相關問題