1

私は、複数の項目に対して3つの可能な結果(エラー、無効、成功)を持つメソッドに取り組んでいます。これらのそれぞれについて、エラー、無効、成功したアイテムを識別するjsonリストを返す必要があります。

私の現在の試みは次のとおりです。Object私は自分のオブジェクトが完全に説明するのに時間がかかりすぎるクラスを表すために使用しました。このObjectクラスには、process成功またはエラーを示すブール値を返し、オブジェクトが無効な場合に例外をスローするメソッドがあります。

def process(list: List[Objects]) = {
    val successIds = new ListBuffer[Int]();
    val errorIds = new ListBuffer[Int]();
    val invalidIds = new ListBuffer[Int]();

    list.foreach( item => {
        try {
            if (item.process) {
                successIds ++ item.id
            } else {
                errorIds ++ item.id
            }
        } catch {
            case e: Exception => invalidIds ++ item.id
        }
    })

    JsonResult(
        Map("success" -> successIds, 
            "failed" -> errorIds, 
            "invalid" -> invalidIds)
    ) 
}

問題は、可変データ構造の使用があまり「Scala-y」ではないことです。私はこれらのリストをもっと機能的な方法で構築したいと思っていますが、私はscalaにまったく慣れていません。これがどのように行われるかについての考えやヒントはありますか?

私は、flatMapメソッドのようなものを使用しています。これは、コレクションのタプルを取得し、flatMapメソッドが単一のコレクションに対して行うのと同じ方法でそれらを照合します。

def process(list: List[Objects]) = {

    val (success, error, invalid) = list.flatMap( item => {
        try {
            if (item.process) {
                (List(item.id), List.empty, List.empty)
            } else {
                (List.empty, List(item.id), List.empty)
            }
        } catch {
            case e: Exception => 
                (List.empty, List.empty, List(item.id))
        }
    })

    JsonResult(
        Map("success" -> success, 
            "failed" -> error, 
            "invalid" -> invalid)
    ) 
}
4

3 に答える 3

8

flatMapここで必要なものではありません-必要ですgroupBy

def process(list: List[Objects]) = {

  def result(x: Objects) =  
    try if (x.process) "success" else "failed"
    catch {case _ => "invalid"}     

  JsonResult(list groupBy result mapValues (_ map (_.id)))
}
于 2012-05-30T15:19:30.263 に答える
1

常に再帰があります:

class Ob(val id: Int) { def okay: Boolean = id < 5 }


@annotation.tailrec def process(
  xs: List[Ob], 
  succ: List[Int] = Nil,
  fail: List[Int] = Nil,
  invalid: List[Int] = Nil
): (List[Int], List[Int], List[Int]) = xs match {
  case Nil => (succ.reverse, fail.reverse, invalid.reverse)
  case x :: more =>
    val maybeOkay = try { Some(x.okay) } catch { case e: Exception => None }
    if (!maybeOkay.isDefined) process(more, succ, fail, x.id :: invalid)
    else if (maybeOkay.get)   process(more, x.id :: succ, fail, invalid)
    else                      process(more, succ, x.id :: fail, invalid)
}

希望どおりに機能します(順序を気にしない場合は、逆をスキップしてください)。

scala> process(List(new Ob(1), new Ob(7), new Ob(2), 
   new Ob(4) { override def okay = throw new Exception("Broken") }))

res2: (List[Int], List[Int], List[Int]) = (List(1,2),List(7),List(4))
于 2012-05-30T15:22:58.263 に答える
0

「オブジェクト」なしでコンパイルできるように調整

def procex (item: String): Boolean = ((9 / item.toInt) < 1)

def process (list: List[String]) = {
    val li: List[(Option[String], Option[String], Option[String])] = list.map (item => {
        try {
            if (procex (item)) {
                (Some (item), None, None)
            } else {
                (None, Some (item), None)
            }
        } catch {
            case e: Exception => 
                (None, None, Some (item))
        }
    })
    li
}
// below 10 => failure
val in = (5 to 15).map (""+_).toList
// 0 to throw a little exception
val ps = process ("0" :: in)

val succeeders = ps.filter (p=> p._1 != None).map (p=>p._1)
val errors     = ps.filter (p=> p._2 != None).map (p=>p._2)
val invalides  = ps.filter (p=> p._3 != None).map (p=>p._3)

動作しないもの:

(1 to 3).map (i=> ps.filter (p=> p._i != None).map (p=>p._i))

_iは機能しません。

于 2012-05-30T15:51:52.633 に答える