2013-11-04 8 views
7

ブール関数を適用するために私がアクセスしているVector of Vectorがあります。すなわち、私はfはタイプT => Booleanである f(myVector(i)(j))の線に沿って何かを実行するつもりですScalaのネストされたSeqの範囲外にデフォルト設定する簡単な方法はありますか?

Vector[Vector[T]]

しかし、これは境界チェックをしません。私は本当にエレガントなものを手に入れることはできません。

私はapplyOrElseを使用することができます。 f(defaultT)false を返すでしょう。しかし、私は、私はだけではなく、機能のデフォルト値を設定することがしたいmyVector.applyOrElse(i, (_:Int) => Vector.empty).applyOrElse (j, (_:Int) => defaultT)

私は私にOptionを与えるためにリフトを使用することができますが、それが第2レベルでうまく構成されていません。 作業を行い、それでも読むことは本当に難しいですmyVector.lift(i) map (_.lift(j) map f getOrElse false) getOrElse false

そして標準の場合/他のブロックがあります:

if (myVector.size <= i) false 
else { 
    val myVector2 = levelVector(i) 
    if (myVector2.size <= j) false 
    else f(myVector2(j)) 
} 

それはちょうど私が達成できるものよりも簡単に分解することができなければならない何かのように思えます。 3層目を追加すると、それはさらに醜いものになります。

他にもオプションがありますか?

免責事項:これはコーセラのprogfunコースから構成されている

答えて

2

が質問から次のコードを取る

myVector.lift(i).flatMap(_.lift(j)).map(f).getOrElse(false) 

重要なアイデアは、Optionのラップ解除(またはマッピング)を延期することです可能な限り。このアプローチは、2次元以上に自然に一般化されます。

これはあなたの答えでfor -comprehension(あなたはそこでliftを含むことを意味すると仮定)と同等にかなり近いですが、カッコ内の理解をラップする必要が一度私は個人的に脱糖バージョンが明確に見つける傾向にあります。

+0

素晴らしい - 私はオプションを保持しようとしていたが、リストの理解の基本を忘れていた。ありがとう。 – Stephen

+0

2.10短いバージョン: 'myVector.lift(i).flatMap(_。lift(j))。exists(f)' – lpandzic

0

I少し行き過ぎているように見える場合でも、エレガントなようです考え出した何かしました:

(for { 
    myVector2 <- myVector(i) 
    t <- myVector2(j) 
} yield t) map f getOrElse false 

はこの賢明ですか?それは確かに読める。それは遅いですか? foldはScalaの2.10で導入される前に、

myVector.lift(i).flatMap(_.lift(j)).fold(false)(f) 

をまたは:次のように

myVector.lift(i) map (_.lift(j) map f getOrElse false) getOrElse false 

これを書き換えることができます。

関連する問題