【问题标题】:Fastest way to encode and decode data in scala在 scala 中编码和解码数据的最快方法
【发布时间】:2017-04-21 16:41:01
【问题描述】:

我有以下 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 并尝试构建一个 Scala Map[String, Map[Int, Map[String, Map[Int, Int]]]] 但考虑到我有几千条记录,这不是很可扩展。开始和停止范围是不相交的,并且必须与其他行相关。

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

【问题讨论】:

  • 你能发布你的代码吗?
  • 所有记录的间隔是否不相交?
  • @Laurent 是的,它们在所有记录之间是不相交的
  • @Amanda,我对 Scala 的了解不足以提供答案,但从数据结构的角度来看,您可以使用区间树基于区间进行有效查找(尽管在内存不是很多)。例如,Guava 库中的 TreeRangeMap 类是一个实现。

标签: scala csv data-structures encoding hashmap


【解决方案1】:

这是一个使用案例类作为键 (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)

【讨论】:

  • 感谢 Tzach,非常有趣的方法。
  • 那里需要 .flatMap 吗?我想只要 .find 就可以了。
  • 我看不到 flatMap 的解决方法,也找不到删除它的理由 - persons.get(...) 的结果是 Option[List[...]],而不是列表本身,所以你想映射列表(如果存在)到Optional[RangeAndPoint],然后将flatten 生成的Option[Option[RangeAndPoint]] 转换为所需的Option[RangeAndPoint]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多