2017-04-21 12 views
0

解碼數據,我有以下csv文件:最快的方式編碼和斯卡拉

Name Age City Start Stop Point 
Mike 29 Fuji 10  30  5 
Mike 29 Fuji 0  10  7 
Susan 26 Fuji 77  1000 9 

我試圖訪問點,給出的姓名,年齡,城市和範圍

實例給出:

Mike, 29, Fuji, 15 will yield 5 
Mike, 29, Fuji, 5 will yield 7 
Susan, 26, Fuji, 990 will yield 9 
Susan, 26, Fuji, 1500 will yield 0 since there's no match 

我讀了CSV,並試圖構建一個斯卡拉地圖[字符串,地圖[詮釋,地圖[字符串,地圖[INT,INT]]]]但由於我有幾千條記錄,是不是很可擴展性。開始和結束範圍是不相交的,並且必須與其他行關聯。

如何在不使用SQL數據庫或KeyValue存儲的情況下高效地對這些數據進行編碼和解碼?任何幫助將不勝感激。

+0

您可以發佈您的代碼嗎? – cheseaux

+0

所有記錄之間的間隔是否不相交? – Laurent

+0

@Laurent是的,它們在所有記錄之間是不相交的 – Amanda

回答

0

這是一個天真的版本,使用案例分類的關鍵(Person)和範圍(RangeAndPoint) - 有一些缺失的細節在帖子中(例如是包含/排他性的範圍?它們是否脫節?應該是什麼結果沒有找到匹配範圍?如果找到多個)? - 但這些可以在答案中修復:

case class Person(name: String, age: Int, city: String) 

case class RangeAndPoint(start: Int, end: Int, point: Int) { 
    def inRange(value: Int): Boolean = value < end && value >= start 
} 

// Let's assume CSV was read into such a format - I'll hard-code it here for the example: 
val persons: Map[Person, List[RangeAndPoint]] = Map(
    Person("Mike", 29, "Fuji") -> List(RangeAndPoint(10, 30, 5), RangeAndPoint(0, 10, 7)), 
    Person("Susan", 26, "Fuji") -> List(RangeAndPoint(77, 1000, 9)) 
) 

// returns the expected result or None if no match found: 
def getPoint(name: String, age: Int, city: String, value: Int): Option[Int] = { 
    persons 
    .get(Person(name, age, city)) 
    .flatMap(_.find(_.inRange(value))) 
    .map(_.point) 
} 

println(getPoint("Mike", 29, "Fuji", 15)) // Some(5) 
println(getPoint("Mike", 29, "Fuji", 5)) // Some(7) 
println(getPoint("Susan", 26, "Fuji", 990)) // Some(9) 
+0

謝謝Tzach,非常有趣的做法。 – Amanda

+0

它需要一個.flatMap嗎?我想只是.find會工作。 – Amanda

+0

我看不到'flatMap'的一種解決方法,也沒有理由刪除它--eatures.get(...)'的結果是一個'Option [List []]',而不是列表本身,所以你希望將列表(如果存在的話)映射到一個'Optional [RangeAndPoint]'中,然後'將選項[Option [RangeAndPoint]]平鋪到所需的'Option [RangeAndPoint]'中。 –