Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Scala中查找每个客户的总花费_Scala - Fatal编程技术网

在Scala中查找每个客户的总花费

在Scala中查找每个客户的总花费,scala,Scala,我正在制定一个简单的要求,以了解每个客户的总花费。如果客户没有花费任何东西,那么我需要向他显示总计花费金额为0 custs.txt: 100,Surender 101,Raja 102,Vijay 100,2015-01-29,20 100,2015-01-30,18 101,2015-01-14,30 101,2015-01-17,20 txns.txt: 100,Surender 101,Raja 102,Vijay 100,2015-01-29,20 100,

我正在制定一个简单的要求,以了解每个客户的总花费。如果客户没有花费任何东西,那么我需要向他显示总计花费金额为0

custs.txt:

 100,Surender
 101,Raja
 102,Vijay
 100,2015-01-29,20
 100,2015-01-30,18
 101,2015-01-14,30
 101,2015-01-17,20
txns.txt:

 100,Surender
 101,Raja
 102,Vijay
 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)
        }
 }

 } 
scala中有简单的连接关键字吗?如果我们需要基于两个文件之间的公共键获取值,那么我们不能在scala中使用类似Join(内部连接,左连接)的东西吗

在这里,我使用scala集合映射,并对每个客户进行迭代


我们能用简单的scala代码行实现同样的要求吗?

让我们看看基础知识。内部联接和外部联接是SQL for数据库的一部分。如果您有一个SQL数据库,您可以使用Scala来查询它,并可以执行连接操作。如果您的数据是csv文件的集合,那么您需要一个引擎将其转换为支持SQL的RDBMS,然后可以进行连接

换句话说,在Scala中,就像在Java、C#或任何其他语言中一样,数据库是在开发过程中制定的实现细节。没有任何其他语言可以在不使用某种包装器AFAIK的情况下直接连接文件


如果我必须做您在这里展示的事情,我会将我的csv文件导入一个SQL数据库,从SQLite到Oracle、SQL server、Mysql,您可以选择,然后通过JDBC查询该数据库,最坏的情况是

在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)
通过将
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

联接操作作为一个概念存在于SQL之外。可以用任何语言实现键值数据结构的联接操作。一旦OP将数据从TXT文件加载到这种数据结构中,使用外部服务来执行连接似乎有点过火。这不是一个真正有用的答案。正如@PabloFranciscoPérezHidalgo所指出的,
join
不是SQL独有的,而且可以很容易地在scala中完成,正如另一个答案所指出的。当然。对任何你个人不同意的事情都可以随意否决。然而,连接实际上是一个关系数据库概念。您可以通过遍历两个列表来模拟它,这一事实是通用的,并且完全不是Scala特有的。正如我在回答中所说,您需要实现一个包装器,这正是另一个答案所做的。我可以用任何语言做那件事。经过一些练习,我相信你也会的。def join[K,A,B](A:Map[K,A],B:Map[K,B]):Map[K,(A,B)]=for((K,va)@SurenderRaja方括号内是该方法的类型参数,用于处理具有任何类型的键和值的映射。@SurenderRaja结果是一个包含连接值的元组。您可以使用哪种类型存储两个不同类型的实例?元组。例如:您有一个从整数到字符串和另一个从整数到双精度的值。如果将它们合并,则生成的映射值的唯一合理的结果类型是(string,double)让我们假设是否希望返回为map[K,C],这里C是字符串def join[K,a,B,C](custs:map[K,a],txns:map[K,B]):map[K,C]={for((K,va)@SurenderRaja如果您想为结果
C
添加一个参数类型,那么您需要提供一个函数,从
a
类型的值和
B
类型的值中构建该类型的值:
def join[K,a,B,C](a:Map[K,a],B:Map[K,B],合并器:(a,B)=>C:Map[K,(a,B)]=for((K,va)
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)