Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.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
Perl 创建和积累地图的地图的地图的地图。。。在斯卡拉_Perl_Scala - Fatal编程技术网

Perl 创建和积累地图的地图的地图的地图。。。在斯卡拉

Perl 创建和积累地图的地图的地图的地图。。。在斯卡拉,perl,scala,Perl,Scala,我有一个包含销售人员、产品、位置、销售价值等数据的文件 例如: Bob, Carrots, United States, 200 Bill, Potatoes, England, 100 Bob, Oranges, England, 50 Bob, Carrots, United States, 20 在perl中,可以使用以下代码将SalesValue简洁地累积到hash of hash的hash中 while(<>){ @cols = split(/,/); $

我有一个包含销售人员、产品、位置、销售价值等数据的文件

例如:

Bob, Carrots, United States, 200
Bill, Potatoes, England, 100
Bob, Oranges, England, 50
Bob, Carrots, United States, 20
在perl中,可以使用以下代码将SalesValue简洁地累积到hash of hash的hash中

while(<>){
    @cols = split(/,/);
    $vals {$cols[0]} {$cols[1]} {$cols[2]} += $cols[3];
}
while(){
@cols=分割(/,/);
$vals{$cols[0]}{$cols[1]}{$cols[2]}+=$cols[3];
}

有人对如何在scala中最好地实现map of map的创建和积累有任何建议吗?

我建议将这些映射的合并视为一个
monoid append
操作

首先,我们将贴图的贴图创建为单个元素:

val input = """Bob, Carrots, United States, 200
              |Bill, Potatoes, England, 100
              |Bob, Oranges, England, 50
              |Bob, Carrots, United States, 20""".stripMargin.lines.toList

val mmm = input.map(_.split(", "))
               .map { case Array(n, g, c, v) => Map(n -> Map(g -> Map(c -> v.toInt))) }
mmm
属于类型
List[Map[String,Map[String,Map[String,Int]]]]

    List[Map[String, 
                    Map[String, 
                               Map[String, Int]]]]
然后我们可以
suml
使用像
scalaz
cats
这样的库:

import scalaz._, Scalaz._

println(mmm.suml)
这将打印(未识别):

为了帮助理解
.suml
操作背后发生的事情,我无耻地建议检查一下我去年做的这个演示


编辑

我们还可以将地图的地图视为可折叠的,并使用可折叠地图获得相同的结果:

input.map(_.split(", "))
     .foldMap{ case Array(n, g, c, v) => Map(n -> Map(g -> Map(c -> v.toInt))) }

Filippo Vitale代码更简洁、优雅

这是一个暴力解决方案:

val t =
  """Bob, Carrots, United States, 200
    |Bill, Potatoes, England, 100
    |Bob, Oranges, England, 50
    |Bob, Carrots, United States, 20""".stripMargin

def commaSplit(s: String) = s.splitAt(s.indexOf(","))

def f(arg: Seq[String]) =
  arg
    .groupBy(commaSplit(_)._1)
    .map{ case (key, values) => key -> values.map(commaSplit(_)._2.drop(2))}

val res =
  f(t.split("\n"))
    .map{ case (key, values) => key -> f(values).map { case (k, v) =>
      k -> f(v).map { case (country, amount) => country -> amount.map(_.toInt).sum }
    }}
这就产生了这样的结果:

Map(Bob ->  Map(Carrots  -> Map(United States -> 220), 
                Oranges  -> Map(England -> 50)), 
    Bill -> Map(Potatoes -> Map(England -> 100)))

换句话说,Perl是这里的赢家;)。。。是的,但是我在再次使用它之前会等待Perl6:-P在这个巨魔之后,我会用一些更详细的解释和替代答案更新答案
Map(Bob ->  Map(Carrots  -> Map(United States -> 220), 
                Oranges  -> Map(England -> 50)), 
    Bill -> Map(Potatoes -> Map(England -> 100)))