在scala中编码和解码数据的最快方法

时间:2017-04-21 16:41:02

标签: scala csv data-structures encoding hashmap

我有以下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

我正在尝试访问Point,给定名称,年龄,城市和范围

给出的例子:

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并尝试构建一个Scala Map [String,Map [Int,Map [String,Map [Int,Int]]]]但是由于我有几千条记录,所以它不是很容易扩展。起始和停止范围是不相交的,必须与其他行相关联。

如何在不使用SQL数据库或KeyValue存储的情况下高效编码和解码此数据?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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)