1

こんにちはこれを変換する方法

for (w <- m ){ val w = (w._2.collect { case x if (x._2 > 0) => x._2; case x if (x._2 < 0) => x._2 }) // if I add here .sum i got sum of (negative and positive) together }

1つの収集で正の値の合計と負の値の合計を取得するには、List(positive.sum、negative.sum)または2つの値にすることができます。

編集:groupby、slice、collect、sum、yieldのみ

私は作業プログラムを書きましたが、2つの収集を行っているため、受け入れられませんでした。


val m = d.groupBy(_._1.slice(0, 7))
    for (w<- m) {
     val x = (w._2.collect { case x if (x._2>  0) =>  x._2 }).sum
     val y = (w._2.collect { case x if (x._2<  0) =>  x._2 }).sum
      println("%7s %11.2f %11.2f %11.2f" format(w._1 , x , y ,(x+y)))
    }
}
エントリーデータは

val d = List(("2011-01-04", -137.76), ("2011-01-04", 2376.45), ("2011-01-04", -1.70), ("2011-01-04", -1.70), ("2011-01-04", -1.00), ("2011-01-06", 865.70), ("2011-01-07", -734.15), ("2011-01-05", -188.63), ("2011-01-06", -73.50), ("2011-01-07", -200.00), ("2011-01-09", -215.35), ("2011-01-09", -8.86), ("2011-01-09", -300.00), ("2011-01-11", -634.54), ("2011-01-11", -400.00), ("2011-01-12", -92.87), ("2011-01-13", -1839.24), ("2011-01-13", 10000.00), ("2011-01-13", -10000.00), ("2011-01-15", -127.97), ("2011-01-15", -319.02), ("2011-01-19", -549.00), ("2011-01-21", -164.80), ("2011-01-23", -500.00), ("2011-01-25", -377.97), ("2011-01-26", 2158.66), ("2011-01-26", -130.45), ("2011-01-27", -350.00), ("2011-01-29", -500.00), ("2011-02-01", 2376.45), ("2011-02-01", 955.00))

4

4 に答える 4

3

私はこの宿題を認識しています:)

したがって、mはであるように見えMap、出力のキーについてはあまり気にしないので(おそらく、この時点ですでにfilterKeysを使用している)、値を引き出してからフィルタリングするのがおそらく最も簡単です-これらの面倒なタプルをすべて避けてください彼らの下線...

val values = m.values
val positives = values filter { _ >= 0 }
val negatives = values filter { _ < 0 }

partitionまたは、必要に応じて、次の方法を使用してこれを整理(およびより効率的に)することができます。

val (positives,negatives) = m.values partition { _ >= 0 }

または、いわゆる「ポイントフリー」スタイルを使用することもできますが、それでは行き過ぎになる可能性があります。

val (positives,negatives) = m.values partition { 0 < }

あなたは今何をすべきかを理解するのに問題はないはずですpositivesそしてnegatives

于 2011-01-23T15:04:02.247 に答える
1

アキュムレータを利用した内部関数で再帰を使用します。

def sumIt(input:List[Tuple2[Int,Int]):Tuple2[Int,Int}={
    def sum_vals(entries:List[Tuple2[Int,Int]], acc:Tuple2[Int,Int]):Tuple2[Int,Int]={
        entries match{
            case x::xs => if(x._2 < 0){ 
                    sum_vals(xs, (acc._1, acc._2+x._2))
                } 
                else{ 
                    sum_vals(xs, (acc._1+x._2, acc._2))
                }
            case Nil => acc
        }
    }
    sum_vals(input, (0,0))
}

ここで、返されたタプルの最初の項目にすべての負の値を保持し、2番目の項目に負の値を保持する必要があると想定しています。

編集:

FoldLeft、FoldLeftの観点から考える必要があります。

def sum_vals(left:Tuple2[Int,Int], right:Tuple2[Int,Int])={
    if(right._2 < 0){
        (left._1, left._2 + right._2)
    }
    else{
        (left._1+right._2, left._2)
    }
 }

myCollection.foldLeft((0,0))( x,y => sum_vals(x,y) )
于 2011-01-23T14:30:28.543 に答える
1

Map [String、Map [String、Int]]のようなマップのマップを使用していると仮定します。この場合、ソリューションは次のようになります。

val m = Map("hello" -> Map("a" -> 1, "b" -> -5, "c" -> 3, "d" -> -2))

val sums = m map {
  case (k, v) =>
    k -> (v.values partition (_ > 0) match {
      case (p, n) => (p.sum, n.sum)
    }).productIterator.toList
}

println(sums)

出力は次のようになります。

Map(hello -> List(4, -7))

それでも理解のために使用したい場合は、次のようになります。

for (w <- m) {
  val sums = (w._2.values.partition(_ > 0) match {
    case (p, n) => (p.sum, n.sum)
  }).productIterator.toList
}

(Scala 2.8.1でテスト済み)

于 2011-01-23T15:15:44.043 に答える
1

解決策は次のとおりです。

val m = for ((k, v) <- d.groupBy(_._1.slice(0, 7))) yield k -> (for ((t, nums) <- (for ((s, l) <- (for ((date, num) <- v) yield (num, if (num > 0) 'positive else 'negative)).groupBy(_._2)) yield s -> (for ((num, _) <- l) yield num))) yield t -> nums.sum)

for ((month, nums) <- m; positive <- nums.get('positive) orElse Some(0D); negative <- nums.get('negative) orElse Some(0D)) {
  println("%7s %11.2f %11.2f %11.2f" format(month, positive, negative, positive + negative))
}

ソリューションと同じ結果が得られ、slice、groupBy、sum、yield(収集が必要な人:)のみが使用されます。今度は別の試行-これを理解するようにしてください:)(そして最適化されるかもしれません)

于 2011-01-23T16:36:31.820 に答える