我正在制定一个简单的要求,即找出每个客户的totalSpent。如果客户没有花费任何东西,那么我需要将TotalSpent Amount显示为0
custs.txt:
100,Surender
101,Raja
102,Vijay
txns.txt:
100,2015-01-29,20
100,2015-01-30,18
101,2015-01-14,30
101,2015-01-17,20
Scala代码:
import scala.io.Source
case class Txns(custId: Int, txn_dateString: String, spentAmount: Int)
object totalamounteachcustomer {
def main (args: Array[String])={
val myCusts=Source.fromFile("C:\\inputfiles\\custs.txt").getLines().toList;
val custsTxns=Source.fromFile("C:\\inputfiles\\txns.txt").getLines().toList;
val TxnsGrped =custsTxns.map { x => {
val Array(custId,txn_dateString,spentAmount) = x.split(",")
Txns(custId.toInt,txn_dateString,spentAmount.toInt)
}
}.groupBy { txn => txn.custId }
for(i <- myCusts)
{
val customer= i.split(",")(0).toInt
val values =TxnsGrped.get(customer)
val TotalSpentAmpunt = values match {
case Some( a:List[Txns]) => a.map { x => x.spentAmount }.sum
case None => 0
}
println(customer+" "+TotalSpentAmpunt)
}
}
}
以上代码有效..
输出:
100 38
101 50
102 0
我们在scala中有简单的Join关键字吗?如果我们需要根据两个文件之间的公共密钥获取值,那么我们不能在scala中使用Join(内连接,左连接)之类的东西吗?
在这里,我使用scala集合Map并对每个客户进行迭代。
我们可以用简单的scala代码行来达到同样的要求吗?
答案 0 :(得分:2)
在Scala中实现地图连接是小菜一碟:
def join[K, A, B](a: Map[K, A], b: Map[K, B]): Map[K, (A,B)] =
for((k,va) <- a; vb <- b.get(k)) yield k -> (va, vb)
使用示例:
val customers = Map(
100 -> "Surender",
101 -> "Raja",
102 -> "Vijay"
)
val purchases = Seq(
(100,"2015-01-29",20),
(100,"2015-01-30",18),
(101,"2015-01-14",30),
(101,"2015-01-17",20)
) groupBy(_._1)
join(customers, purchases) mapValues { case (_, l) => l.map(_._3).sum }
您可以通过将join
包含在隐式类中来实现implicit class C[K, A](a: Map[K, A]) {
def join[B](b: Map[K, B]): Map[K, (A,B)] =
for((k,va) <- a; vb <- b.get(k)) yield k -> (va, vb)
}
customers join purchases
中缀操作:
implicit class C[K, A](a: Map[K, A]) {
def join[B](b: Map[K, B]): Map[K, (A,B)] =
for((k,va) <- a; vb <- b.get(k)) yield k -> (va, vb)
def leftJoin[B](b: Map[K, B], default: B): Map[K, (A,B)] =
for((k,va) <- a; vb = b.getOrElse(k, default)) yield k -> (va, vb)
}
请注意,此连接实现(内部联接)很容易修改为表现为左连接:
customers leftJoin(purchases, Seq()) mapValues {
case (_, l) => l.map(_._3).sum
}
> res: scala.collection.immutable.Map[Int,Int] = Map(100 -> 38, 101 -> 50, 102 -> 0)
然后将它与您的数据一起使用以获得您正在寻找的结果:
select p From Parent as p JOIN FETCH p.children as c where c.age >= 10
答案 1 :(得分:-1)
让我们来看看基础知识。内部和外部联接是数据库的SQL的一部分。如果您有SQL数据库,则可以使用Scala进行查询,并且可以执行连接操作。如果您将数据作为csv文件的集合,那么您需要一个引擎将其转换为支持RDBMS的SQL,然后可以进行连接。
换句话说,在Scala中,如在Java,C#或任何其他语言中,数据库是一个在开发过程中解决的实现细节。没有其他语言可以直接使用某种包装器AFAIK直接连接文件。
如果我必须做你在这里展示的内容,我会将我的csv文件导入SQL数据库,从SQLite到Oracle,SQL服务器,Mysql,接受你的选择,然后查询该数据库,最坏的情况通过JDBC。