0

編集
OK、@dhg は、fold() へのコード ブロックが val にバインドされていない場合にドット メソッド構文が必要であることを発見しました (同じコード ブロックで reduce() を使用すると、スペース メソッド構文を使用できる理由はわかりません)。 )。いずれにせよ、最終結果は非常に簡潔です。

result.map { row =>
  addLink( row.href, row.label )
}.fold(NodeSeq.Empty)(_++_)

これは、元の質問をある程度否定します。つまり、多くの場合、いずれかまたは両方のシナリオを高次から切り離し、「太い」反復的な if/else ステートメントを避けることができます。

ORIGINAL
List[T] のような空の可能性のあるコレクションを操作する場合の if/else 処理を削減しようとしています

たとえば、最新のニュース記事を取得してhtml newsのNodeSeq<li><a>links</a></li>を作成する必要があるとします。

val result = dao.getHeadlines // List[of model objects]
if(result.isEmpty) NodeSeq.Empty
else 
  result map { row =>
    addLink( row.href, row.label ) // NodeSeq
  } reduce(_ ++ _)

これは問題ありませんが、非常に簡潔ですが、次のいずれかまたは両方のケースに対処するために、三項スタイルに移行したいと考えています。

result.isEmpty ? NodeSeq.Empty :
  result map { row =>
    addLink( row.href, row.label )
  } reduce(_ ++ _)

三項をブール値にポンピングするという古い投稿を見たことがありますが、if/elseを合理化するための代替手段があれば知りたいですか?

match {...}IMOは、このシナリオでは少し肥大化しており、for {...} yieldあまり役に立たないようです.

4

1 に答える 1

3

空をチェックする必要はまったくありません。sincefoldの代わりに使用するだけで、デフォルトの「空の」値を指定できます。reducefold

scala> List(1,2,3,4).map(_ + 1).fold(0)(_+_)
res0: Int = 14

scala> List[Int]().map(_ + 1).fold(0)(_+_)
res1: Int = 0

の例を次に示しListますSeq

scala> List(1,2).map(Seq(_)).fold(Seq.empty)(_++_)
res14: Seq[Int] = List(1, 2)

scala> List[Int]().map(Seq(_)).fold(Seq.empty)(_++_)
res15: Seq[Int] = List()

編集:サンプルの問題は、.メソッド間のドット()文字の削除に関係しているようです。それらを保持すると、すべて機能します。

scala> List(1,2,3).map(i => node).fold(NodeSeq.Empty)(_ ++ _)
res57: scala.xml.NodeSeq = NodeSeq(<li><a href="/foo">Link</a></li>, <li><a href="/foo">Link</a></li>, <li><a href="/foo">Link</a></li>)
于 2012-04-08T18:26:51.997 に答える