2016-09-11 4 views
1

私は以下のような擬似コードを持っています。 ItemChurner.churn()は、x回までオブジェクトを生成する抽象化されたコンポーネントであり、xは不明です。 :スカラ:var型または可変型を避ける

def func: MyList = { 

    var list: MyList = MyList() 

    while(ItemChurner.canChurn) { 
     list = new MyList(ItemChurner.churn(), list) 
    } 

    list 
} 

varの使用を避ける方法はありますか?

+1

のような 'Iterator'インターフェースを実装することができます。' val iterator = new Iterator {def hasNext = ItemChurner.canChurn; def next = ItemChurner.churn() '、次に' iterator.toList' – dk14

+1

なぜ 'while'ループの内部をtry-catchでラップしていますか? 'ItemChurner'は要素がなければ' false'を返すべきではありませんか? –

+0

@YuvalItzchakov:そうです。スニペットを修正しました。 – Mohitt

答えて

4

canChurn作品それが必要としている場合:

def func(churner: ItemChurner) = { 
    val iterator = new Iterator { 
    def hasNext = churner.canChurn 
    def next = churner.churn() 
    } 
    iterator.toList 
} 

(質問の)バージョンについてchurn()ためcatched例外のチェックを含んでいた:

実際にいくつかの例外を期待していた場合、何ですポイントはcanChurn?とにかく

、あなたは例外心配している場合:

Iterator.continually(Try(churner.churn)).takeWhile(_.isSuccess).map(_.get).toList 

churnが伝播する必要がある他のいくつかの例外をスローするので、ここではScalaのException helpers)の手になるかもしれないので、これは実際には、あまり正確ではありません。

def step = catching(classOf[NoMoreElementsException]) opt churner.churn() 
Iterator.continually(step).takeWhile(_.nonEmpty).map(_.get).toList 
+0

@ dk12、はい。ちょうど私がcanChurnを持っている場合、例外をキャッチする必要はないことを認識しました。指摘してくれてありがとう。質問が更新されました。 – Mohitt

+0

@ dk12 Iterator.continually(if(churner.canChurn)Some(churner.churn())elseなし).takeWhile(_。isEmpty).map(_。get).toList'はより良い選択です'churner'機能の露出部分だけに依存しています。 –

+0

@SarveshKumarSinghはそれに依存します。 'Try'の内部で例外をキャッチするのは遅くなるかもしれませんが、実際にはそれ以上の要素についてはシグナルを出さない正確な例外をチェックするコードのほうがはるかに劣ります([例外ヘルパー](http://www.scala-lang.org/api/) current /#scala.util.control.Exception $)) – dk14

4

単純再帰を使用して、varを避けたい場合は、これは、関数型プログラミングで使用される一般的な戦略です。

利用Vectorの代わりに、効果的なappend

def func[T](): List[T] = { 

    @tailrec 
    def helper(result: List[T]): List[T] = { 
    if (ItemChurner.canChurn) helper(result ++ List(ItemChurner.churn)) 
    else result 
    } 

    helper(List.Empty[T]) 
} 

ためListItemChurner.canChurnは、任意の例外をスローしないと仮定。例外をスローすると単純に内部にラップされます。Try

+0

有効性については、 'List ++ List'は線形の複雑さを持っているので、' List'は最良の選択ではないようです。 'Vector' [has](http://docs.scala-lang.org/overviews/collections/performance-characteristics.html)効果的に定数を追加 – dk14

+0

@ dk14あなたは間違いなしです。ありがとう。ansを編集しました。 – pamu

0

pamuの回答を改善すると、次のような行ができます。

def func: MyList = { 
    def process(cur: MyList): MyList = { 
    if (ItemChurner.canChurn) process(new MyList(ItemChurner.churn(), cur)) 
    else cur 
    } 
    process(new MyList()) 
} 
関連する問題