2016-01-15 4 views
5

に... SalesValueたとえば、私はセールスマン、製品、場所のデータを含むファイルを持っているのScala

を作成し、地図の地図の地図を蓄積:

Bob, Carrots, United States, 200 
Bill, Potatoes, England, 100 
Bob, Oranges, England, 50 
Bob, Carrots, United States, 20 

SalesValueを簡潔にすることができ次のコード

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

を使用してperlでハッシュのハッシュのハッシュの中に蓄積された誰もが、マップのマップに加え、蓄積のマップのこの作成は、最高の私可能性がどのように任意の提案を持っていますスカラーで実装されていますか?

答えて

6

これらのマップをマージして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]]]] 

その後、我々はscalazまたはcatsのようなライブラリを使用してsumlできます

import scalaz._, Scalaz._ 

println(mmm.suml) 

これは(identedない)を印刷します:

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

は、私はは臆面もなくは、私が昨年https://speakerdeck.com/filippovitale/will-it-blend-scalasyd-february-2015


EDIT作られたこのプレゼンテーションをチェックアウトすることをお勧め.suml操作の背後に何が起こっているのかを理解しやすくするために

マップの地図の表示もFoldableですそして、同じ結果のためfoldMapを使用します。

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

つまり、ここではPerlが勝者です;) – Ashalynd

+0

...はい、しかし私はPerl6を待っていますこれをもう一度使う前に:-Pこのトロルの後、私はいくつかの詳細な説明と別の答えで答えを更新します –

+0

Map oof Mapsの地図を読む素晴らしい方法... – BarneyW

0

フィリッポ・ヴィターレコードがより簡潔かつ

エレガントです。これは、ブルートフォースソリューションです:

Map(Bob -> Map(Carrots -> Map(United States -> 220), 
       Oranges -> Map(England -> 50)), 
    Bill -> Map(Potatoes -> Map(England -> 100))) 
:この結果を与える

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 } 
    }} 

関連する問題